Building This Blog with Next.js and Markdown

This blog runs on a deliberately small stack: markdown files in a Git repo, compiled to HTML at build time. No CMS, no database, no content API. The files are the content layer.

How a post becomes a page

Every .md file in content/blog/ flows through a unified pipeline:

const file = await unified()
 .use(remarkParse)    // markdown -> mdast
 .use(remarkGfm)     // tables, strikethrough, task lists
 .use(remarkRehype)    // mdast -> hast
 .use(rehypeSlug)     // id="..." on headings
 .use(rehypeShiki, {   // syntax highlighting at build time
  themes: { light: "github-light", dark: "github-dark" },
 })
 .use(rehypeStringify)  // hast -> html string
 .process(markdown)

The result is a static HTML string. Because it's all build-time, there's zero client-side JavaScript shipped for rendering content.

Why not a CMS?

The files are version-controlled, portable, and outlive any platform.

A few things I get for free:

  • Ownership content lives next to code, in my repo
  • Speed everything prerenders to static HTML
  • Longevity markdown will still open in 20 years

When I outgrow hand-rolling the content layer, I'll move to a typed schema but not before I need it.

Comments