Making this website
I find myself scrolling through Twitter from time to time. Maybe more than I admit.
I'm a big fan of the "build in public" crowd, and while I might not be the most social software developer, I enjoy keeping up with industry updates and trends.
Back in 2024, I stumbled upon Emil Kowalski and his work. His website resonated with me. It's beautifully done, and encapsulates the style of his work really well.
I liked it so much, I wanted to see if I could recreate it. It's closed-source, so I thought it would be a fun little challenge.
Technical decisions
Planning on starting from scratch, I had to pick my tech stack.
I chose Next.js due to my familiarity with it. I think it's a great all-in-one framework for small- to medium-sized projects.
I also chose Tailwind CSS and shadcn/ui for styling. I am not a fan of traditional CSS, and I've been a huge fan of Tailwind since I first discovered it in college. As for shadcn/ui, that was for some pre-built components and consistent theming.
Since I'm the only one writing on this site, I wanted to stick with Markdown files because it's familiar and easy to write. I didn't want to deal with setting up a , and I can take Markdown almost anywhere if I need to.
Most of the tools I've described above are pretty common. There's one new tool I recently got to experiment with, and I'll talk more about it next.
Markdown rendering
While working on The Grug Brained Chatbot, I stumbled upon the Streamdown tool by Vercel. It's a drop-in replacement for the react-markdown package, specifically designed for AI-powered streaming.
Now you're probably thinking, "This blog isn't AI-powered or streamed, what gives?"
While reading the documentation, I noticed that it has a mode for rendering static Markdown. I thought it would be great for a blog, especially since it comes with a bunch of preconfigured remark and rehype plugins out of the box.
Conclusion
In short, blog posts start as Markdown files. They're read using the filesystem, and fed into Streamdown. Frontmatter gets parsed using basic regex, since I don't plan on having complex frontmatter values. Everything else is just native Next.js.
I think it's pretty simple, and I'm happy with how it turned out. It's not an exact replica of Emil's website, primarily due to my laziness, but I never wanted it to be exact.