I wanted the new site to feel modern but stay boring where it counts: fast, static, and easy to write for. Here's the stack and a few of the decisions.

The stack

  • Next.js 15 (App Router, React Server Components)
  • Tailwind CSS v4 with its new CSS-first config
  • Shiki via rehype-pretty-code for syntax highlighting
  • Framer Motion for tasteful entrance animations

Tailwind v4 is CSS-first

No more tailwind.config.js. Tokens live in your stylesheet now:

globals.css
@import "tailwindcss";
@plugin '@tailwindcss/typography';
 
@custom-variant dark (&:where(.dark, .dark *));
 
@theme {
  --font-heading: var(--font-space-grotesk), sans-serif;
  --color-brand: #8b7cff;
}

Server-side highlighting with Shiki

The markdown pipeline runs entirely on the server, so the browser only ever receives ready-to-paint HTML — no highlighting library shipped to the client:

markdown.ts
import rehypePrettyCode from "rehype-pretty-code";
import rehypeStringify from "rehype-stringify";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import { unified } from "unified";
 
export async function transformMarkdown(markdown: string) {
  const file = await unified()
    .use(remarkParse)
    .use(remarkRehype)
    .use(rehypePrettyCode, {
      theme: { light: "github-light", dark: "github-dark" }, 
    })
    .use(rehypeStringify)
    .process(markdown);
 
  return file.toString();
}

Because the themes are defined as a { light, dark } pair, a couple of CSS variables swap the colours when you toggle the theme — no re-render required.

A tiny bit of Python, for variety

def fib(n: int) -> list[int]:
    a, b = 0, 1
    out = []
    for _ in range(n):
        out.append(a)
        a, b = b, a + b
    return out
 
 
print(fib(10))  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

And a shell snippet, because every blog needs one:

npx create-next-app@latest my-site --ts
cd my-site && npm run dev

That's the whole trick. Static HTML, highlighted on the server, with a design system that lives in CSS. Fast to load, fast to write for.