franco-shum.com
My personal site, with a blog on working with AI coding agents, an about page, and this projects section.

The problem
I wanted somewhere to write longer posts about how I work, mostly with AI coding agents, and to show what I've built. It had to be cheap to keep up. Adding a post or a project should mean writing one file, not logging into a CMS.
What I built
The site uses the Next.js App Router with React 19 and the React Compiler, is styled with Tailwind CSS v4, and is deployed on Vercel. Blog posts and projects are MDX files in the repo. An animated aurora sits behind every page, and the about page has a small Toronto city scene built with three.js through react-three-fiber.
Decisions worth explaining
Content is files, checked at build time
Velite compiles the MDX at build time and checks each file's frontmatter against a schema. Titles have a length limit, links have to be valid URLs, and a cover has to be an image file that exists. A mistake fails the build instead of shipping a broken page. The output is typed data that the pages import directly, so there's no database or API between the content and the page. Velite also measures each cover and computes its blur placeholder, which next/image uses while the image loads.
Code colours come from the design tokens
Code blocks are highlighted by shiki through rehype-pretty-code, with a CSS-variables theme instead of a stock one. Shiki writes variable references into the markup, and the colours are defined next to the rest of the site's tokens. Code blocks match the palette, and changing a colour means editing one file.