Thomas Nimmo

Highlighted code, the boring way

· mdx, tooling

Syntax highlighting on this blog runs entirely at build time. The MDX body is compiled on the server; rehype-pretty-code turns fenced code into pre-highlighted HTML with per-token spans, so the browser only pays for CSS.

A small example — a typed post reader:

import fs from "node:fs/promises";
import path from "node:path";
import matter from "gray-matter";
 
export type Post = {
  slug: string;
  title: string;
  publishedAt: string;
};
 
export async function getAllPosts(): Promise<Post[]> {
  const dir = path.join(process.cwd(), "content", "posts");
  const files = await fs.readdir(dir);
  const posts = await Promise.all(
    files
      .filter((f) => f.endsWith(".mdx"))
      .map(async (file) => {
        const raw = await fs.readFile(path.join(dir, file), "utf8");
        const { data } = matter(raw);
        return data as Post;
      }),
  );
  return posts.sort((a, b) => b.publishedAt.localeCompare(a.publishedAt));
}

That's it — no client-side highlighter, no useEffect popping tokens in after paint.