Skip to main content
All posts

Hello, World: This Site Has a Blog Now

Why I bolted a minimal MDX blog onto my portfolio instead of reaching for a blog platform.

I write software for a living, so naturally the hardest part of starting a blog was resisting the urge to build a CMS first. This blog is deliberately boring: MDX files in a folder, statically rendered at build time. No database, no admin panel, no excuses.

How it works

Every post is a single .mdx file in content/posts/. Front matter carries the metadata, and the body is Markdown with JSX available when I need it.

lib/posts.ts
export function getAllPosts(options?: { includeDrafts?: boolean }): Post[] {
  return fs
    .readdirSync(POSTS_DIR)
    .filter((file) => file.endsWith(".mdx"))
    .map((file) => readPost(POSTS_DIR, file))
    .filter((post) => options?.includeDrafts || !post.draft)
    .sort((a, b) => b.date.localeCompare(a.date))
}

Publishing a post is a git commit. Drafts are a draft: true flag away from the public eye. That's the whole platform.

What I'll write about

Mostly the things I run into building and running real products:

  • Next.js and TypeScript patterns that earned their keep
  • Running Mosaic Ridge — the business side of shipping
  • The occasional lesson learned the hard way

Ship the thing. Write about it after.

More soon.