Every developer eventually builds their own website. Most never finish it. This is my attempt at actually shipping something.
Why Next.js 15?
I come from a C# / .NET background. Server-side rendering, strong typing, a clear separation between data access and presentation. These things feel natural to me. Next.js 15's App Router brings that same thinking to the frontend.
React Server Components let you write components that run only on the server: they can read from the filesystem, query a database, even make fetch calls directly. No useEffect, no loading states, no client-side data fetching for content that doesn't change per user. It's conceptually similar to a Razor page or a controller action in ASP.NET MVC.
// This runs on the server at build time (SSG) or request time (SSR).
// The `fs` module is fine here. The browser never sees this code.
import fs from "fs";
export async function getPost(slug: string) {
const raw = fs.readFileSync(`content/tech/${slug}.mdx`, "utf-8");
return raw;
}The MDX pipeline
MDX lets you write Markdown with JSX inside it. The pipeline goes:
- gray-matter splits the YAML frontmatter from the content body
- remark-gfm adds GitHub Flavoured Markdown (tables, strikethrough, task lists)
- rehype-pretty-code wraps code blocks with Shiki syntax tokens
- compileMDX from
next-mdx-remote/rscturns it all into React JSX
The result is a clean <article> element styled by Tailwind's prose utility.
Dark mode without JavaScript
One thing I'm proud of: the syntax highlighting works in both light and dark mode with zero client-side JavaScript. rehype-pretty-code writes both colour sets into the HTML. The CSS color-scheme property on <html> controls which one is visible.
:root { color-scheme: light; }
.dark { color-scheme: dark; }next-themes toggles the dark class. The browser CSS does the rest.
What's next
- Add Supabase for persistent data (comments? newsletter?)
- Implement reading time estimates
- Add an RSS feed
- Improve mobile navigation
More posts incoming. The hard part is done: the infrastructure exists. Now I just have to write.