<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Valdeir Sapará</title>
    <link>https://valdeirsapara.com.br/</link>
    <description>Notas sobre programação, experimentos e coisas que estou aprendendo.</description>
    <language>pt-BR</language>
    <lastBuildDate>Wed, 12 Aug 2026 00:00:00 GMT</lastBuildDate>
    <generator>Bun</generator>
    <atom:link href="https://valdeirsapara.com.br/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Construindo meu próprio blog com Bun</title>
      <link>https://valdeirsapara.com.br/2026/08/construindo-meu-proprio-blog-com-bun/</link>
      <guid isPermaLink="true">https://valdeirsapara.com.br/2026/08/construindo-meu-proprio-blog-com-bun/</guid>
      <pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate>
      <description>Construindo meu blog com Bun HTML CSS sem framework</description>
      <category>bun</category>
      <category>typescript</category>
      <category>rss</category>
      <category>html</category>
      <category>css</category>
      <content:encoded><![CDATA[<p>Eu queria criar um blog há algum tempo, principalmente porque tenho o costume de construir coisas, estudar assuntos diferentes e descobrir coisas que acho interessantes, mas quase nunca registro nada disso. A ideia do blog nasceu justamente daí: ter um lugar meu onde eu pudesse escrever sobre o que estou fazendo, o que estou aprendendo e até sobre coisas que ainda estou tentando entender.</p>
<p>Quando comecei a pensar em como construir isso, minha primeira ideia foi fazer da maneira mais simples possível. Eu não queria WordPress, banco de dados, CMS ou um servidor rodando uma aplicação só para entregar meus textos. Pensei que poderia fazer tudo apenas com HTML, CSS e JavaScript, deixando os posts como arquivos Markdown dentro do próprio projeto.</p>
<p>A ideia inicial era basicamente ter algo assim:</p>
<div class="code-block">
  <div class="code-block__bar">
    <span class="code-block__dots" aria-hidden="true"><span></span><span></span><span></span></span>
    <span class="code-block__lang">TEXT</span>
  </div>
  <pre><code>assets/
└── posts/
    ├── primeiro-post.md
    └── outro-post.md</code></pre>
</div>
<p>O JavaScript carregaria o arquivo <code>.md</code>, alguma biblioteca converteria Markdown para HTML e pronto. Pelo menos era o que eu imaginava no começo.</p>
<h2>Eu não precisava de um servidor, precisava de um build</h2>
<p>Conforme comecei a desenvolver, algumas coisas começaram a incomodar. Eu queria que cada artigo tivesse uma URL bonita, como <code>/2026/08/me-aventurando-em-go-sem-aprender-go/</code>. Também queria que a homepage fosse construída automaticamente a partir dos artigos, queria metadata para cada página, RSS e, principalmente, queria entregar HTML pronto em vez de depender do JavaScript do navegador para renderizar o conteúdo.</p>
<p>Foi aí que percebi que estava tentando resolver o problema errado. Eu continuava pensando que as alternativas eram ter ou não ter um servidor, mas eu não precisava de um servidor para fazer essas coisas. Eu precisava de um processo de build.</p>
<p>Eu poderia ter escrito esse gerador em Python tranquilamente, provavelmente seria até o caminho mais confortável para mim. Mas justamente por isso resolvi não fazer. Já tenho bastante coisa em Python e nunca tinha colocado nenhum projeto meu em produção usando Bun. O blog parecia uma oportunidade boa para experimentar.</p>
<p>No final, a stack ficou pequena: Bun, TypeScript, HTML, CSS e Markdown. Não tem React, Next, banco de dados ou CMS. O Bun também não fica rodando em produção. Ele existe apenas para transformar meu conteúdo nos arquivos estáticos que serão publicados.</p>
<h2>Os posts são apenas arquivos</h2>
<p>Eu queria que escrever continuasse sendo a parte mais simples possível. Hoje os artigos ficam organizados dentro do projeto por ano e mês:</p>
<div class="code-block">
  <div class="code-block__bar">
    <span class="code-block__dots" aria-hidden="true"><span></span><span></span><span></span></span>
    <span class="code-block__lang">TEXT</span>
  </div>
  <pre><code>content/
└── 2026/
    └── 08/
        └── primeiro-post.md</code></pre>
</div>
<p>Cada Markdown possui algumas informações no início do arquivo:</p>
<div class="code-block">
  <div class="code-block__bar">
    <span class="code-block__dots" aria-hidden="true"><span></span><span></span><span></span></span>
    <span class="code-block__lang">YAML</span>
  </div>
  <pre><code>---
title: Meu primeiro post
date: 2026-08-10
description: O começo de alguma coisa.
---</code></pre>
</div>
<p>Depois disso é simplesmente Markdown normal. Durante o build, uso <code>Bun.Glob</code> para encontrar todos esses arquivos:</p>
<div class="code-block">
  <div class="code-block__bar">
    <span class="code-block__dots" aria-hidden="true"><span></span><span></span><span></span></span>
    <span class="code-block__lang">TS</span>
  </div>
  <pre><code>const glob = new Bun.Glob(&quot;**/*.md&quot;);</code></pre>
</div>
<p>O nome do arquivo vira o slug do artigo e a data determina sua posição na estrutura do site. Dessa forma, <code>content/2026/08/primeiro-post.md</code> acaba gerando <code>dist/2026/08/primeiro-post/index.html</code>, que por consequência pode ser acessado em <code>/2026/08/primeiro-post/</code>.</p>
<p>Eu gostei bastante desse formato porque existe uma relação muito simples entre o que está no meu repositório e o que aparece na internet. Se daqui a alguns anos eu abrir a pasta <code>content/2026</code>, vou encontrar exatamente os textos que escrevi naquele ano.</p>
<h2>A primeira pequena surpresa veio do Windows</h2>
<p>Enquanto estava construindo essa parte, apareceu um bug interessante. Em determinado momento meu diretório de saída ficou parecido com isso:</p>
<div class="code-block">
  <div class="code-block__bar">
    <span class="code-block__dots" aria-hidden="true"><span></span><span></span><span></span></span>
    <span class="code-block__lang">TEXT</span>
  </div>
  <pre><code>dist/2026/08/2026\08\primeiro-post</code></pre>
</div>
<p>Eu estava desenvolvendo no Windows (isso vai render outro post sobre por que tenho usado Windows) e havia misturado caminhos do filesystem com caminhos que eu estava tratando como URLs. Poderia simplesmente substituir <code>\</code> por <code>/</code>, mas aí estaria criando uma solução que provavelmente voltaria para me incomodar depois.</p>
<p>Resolvi usar <code>node:path</code> para tudo que pertence ao filesystem:</p>
<div class="code-block">
  <div class="code-block__bar">
    <span class="code-block__dots" aria-hidden="true"><span></span><span></span><span></span></span>
    <span class="code-block__lang">TS</span>
  </div>
  <pre><code>import path from &quot;node:path&quot;;

const slug = path.basename(filename, &quot;.md&quot;);

const outputDir = path.join(
  &quot;dist&quot;,
  year,
  month,
  slug
);</code></pre>
</div>
<p>Para URLs, entretanto, continuo montando o caminho com <code>/</code>:</p>
<div class="code-block">
  <div class="code-block__bar">
    <span class="code-block__dots" aria-hidden="true"><span></span><span></span><span></span></span>
    <span class="code-block__lang">TS</span>
  </div>
  <pre><code>const url = `/${year}/${month}/${slug}/`;</code></pre>
</div>
<p>É uma diferença pequena, mas deixou o build independente do sistema operacional. Posso rodá-lo no Windows durante o desenvolvimento e depois em Linux sem precisar ter condições específicas espalhadas pelo código.</p>
<h2>A homepage também nasce dos Markdown</h2>
<p>Depois que os artigos começaram a ser gerados automaticamente, percebi que não havia motivo para manter a homepage manualmente. O build já estava lendo todos os meus textos e conhecia título, descrição, data, slug e URL de cada um deles. Bastava guardar essas informações enquanto os arquivos eram processados.</p>
<p>Criei então uma representação simples para cada artigo:</p>
<div class="code-block">
  <div class="code-block__bar">
    <span class="code-block__dots" aria-hidden="true"><span></span><span></span><span></span></span>
    <span class="code-block__lang">TS</span>
  </div>
  <pre><code>type Post = {
  title: string;
  description: string;
  date: Date;
  slug: string;
  url: string;
};</code></pre>
</div>
<p>Depois de processar os Markdown, os artigos são ordenados pela data e usados para gerar o <code>index.html</code>. Também resolvi agrupá-los por mês, porque gosto da ideia de a homepage funcionar como um arquivo cronológico. Conforme eu escrever, quero conseguir olhar para trás e encontrar agosto de 2026, setembro de 2026, 2027 e assim por diante.</p>
<p>Isso tem bastante relação com o motivo pelo qual criei este blog. Não quero que ele seja apenas uma coleção de tutoriais. Quero que, com o passar do tempo, ele se torne um registro do que eu estava construindo e pensando em diferentes momentos.</p>
<h2>E eu queria RSS</h2>
<p>RSS era uma das poucas funcionalidades que eu já sabia que queria antes mesmo de começar. Gosto muito da ideia de poder acompanhar um site sem depender de uma plataforma decidindo o que deve aparecer em um feed. Se alguém quiser acompanhar o que escrevo, existe um <code>feed.xml</code>, a pessoa adiciona ao leitor que quiser e acabou.</p>
<p>Também achei curioso estar construindo o blog com Bun, uma tecnologia relativamente nova, e ao mesmo tempo fazendo questão de suportar RSS, uma tecnologia que existe há décadas. No fim, as duas coisas convivem perfeitamente porque o resultado do build continua sendo apenas arquivos.</p>
<p>Hoje o fluxo do blog é basicamente este:</p>
<div class="code-block">
  <div class="code-block__bar">
    <span class="code-block__dots" aria-hidden="true"><span></span><span></span><span></span></span>
    <span class="code-block__lang">TEXT</span>
  </div>
  <pre><code>Markdown
    ↓
   Bun
    ↓
Posts + Homepage + RSS
    ↓
  dist/
    ↓
arquivos estáticos</code></pre>
</div>
<p>Quem hospeda o site não precisa saber o que é Bun, TypeScript ou Markdown. O processo de build acontece antes da publicação e o servidor recebe apenas HTML, CSS, XML e os demais arquivos estáticos.</p>
<h2>Por que não usar algo pronto?</h2>
<p>Essa provavelmente é a pergunta mais óbvia. Existem diversas ferramentas que já fazem tudo isso. Eu poderia ter usado Astro, Hugo, Jekyll ou até WordPress e provavelmente teria terminado mais rápido.</p>
<p>Mas terminar mais rápido não era necessariamente o objetivo.</p>
<p>Eu comecei esse blog porque queria um lugar para registrar as coisas que construo e aprendo. Nesse contexto, construir o próprio mecanismo que gera o blog acabou fazendo parte da diversão. Em vez de configurar um gerador de sites, eu precisei pensar em como descobrir os artigos, como representar seus metadados, como gerar URLs, como lidar com diferenças entre sistemas operacionais, como montar a homepage e como gerar o feed.</p>
<p>Não criei meu próprio gerador de site estático porque achei que o mundo precisava de mais um. Fiz porque queria entender o problema e porque achei que seria divertido construir.</p>
<p>Agora tenho um projeto pequeno, que consigo abrir e entender praticamente inteiro, onde um arquivo Markdown que escrevo no meu computador termina como uma página publicada em <code>valdeirsapara.com.br</code>.</p>
<p>E talvez daqui a alguns meses eu olhe para esse código e descubra que metade das decisões que tomei foram ruins. Se isso acontecer, ótimo.</p>
<p>Provavelmente vai render outro post.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Bem-vindos!!</title>
      <link>https://valdeirsapara.com.br/2026/08/bem-vindo/</link>
      <guid isPermaLink="true">https://valdeirsapara.com.br/2026/08/bem-vindo/</guid>
      <pubDate>Sat, 08 Aug 2026 00:00:00 GMT</pubDate>
      <description>Iniciando meu blog</description>
      <content:encoded><![CDATA[<p>Olá, sejam todos bem-vindos! Eu passei semanas tomando a decisão de criar ou não um blog, mas minha mulher e alguns amigos acharam que seria uma boa ideia —
afinal, eu sempre gostei de falar sobre programação — e eu me inspirei no que o <a href="https://akitaonrails.com/">akita</a> faz.</p>
<p>Eu sempre gostei de escrever e de falar sobre as muitas coisas que ando estudando, aprendendo, testando e fazendo. A parte chata é que ninguém nunca tem interesse de
ouvir, mas eu gosto de falar. E eu não quero mais ser o amigo chato que fica explicando como funciona uma linguagem de programação de baixo nível ou como meu projeto
foi tão complexo a ponto de me deixar doido — principalmente para quem é de outras áreas. Tenho poucos amigos da área, e nenhum deles gosta de saber o que eu fiz durante meu feriadão.
E, de acordo com a minha psicóloga, eu precisava escrever. Então criei este blog.</p>
<p>Sejam muito bem-vindos!!!</p>
]]></content:encoded>
    </item>
  </channel>
</rss>