Skip to content
All posts
3 min read

The spec came first

I wrote a design document for my own website before writing any code. It is mostly a list of things I am not allowed to do later.

EngineeringSystems

The reasonable way to build a personal website is a template and a Saturday. I spent the Saturday on a design document instead. It is dated May 29, it lives at docs/superpowers/specs/2026-05-29-personal-platform-framework-design.md, and as of this writing there is no code.

I have watched personal sites die, mine included, and they never die of missing features. They die of entropy: a pile of one-off pages, styles pasted between them, a half-finished redesign, and then a year where touching any of it feels like archaeology. The failure is structural, so the fix has to be structural, and structure is exactly the thing you cannot retrofit on a pile.

So the document does not describe a site. It describes a platform with two halves: a public surface, and a private owner console behind auth where all content gets managed. Features are packs: projects, blog, links, each owning its routes, its data shape, and its seed content, so adding one never means smearing code across the codebase. Every route the site serves is declared in one registry, and the sitemap, robots file, and console navigation all derive from that registry. A page that is not registered does not exist anywhere else either, which makes half-tracked pages unrepresentable. Colors, radii, and fonts exist only as design tokens; a theme is one block of token values, and a hardcoded hex anywhere in a component is a violation.

The private half gets equal billing in the document, which surprised me as I wrote it. Content does not live in code; it lives in data I edit through my own console, from a phone if needed, without a deploy. That decision quietly dictates half the architecture: if content is data, every feature pack needs a data shape, an editor, and seed content for an empty database, and suddenly the console is not an appendix to the site. It is the other half of the product, with one user.

Written down like that, half the document turns out to be prohibitions: a list of things I am not allowed to do later. There will be a night when I want to hardcode the color and register the route tomorrow. Future me at 1am is not a trustworthy engineer, and the document outranks whoever shows up at that hour. That is also why the spec lives in the repo, under docs, instead of in a notes app: constraints that version with the code are constraints the code can be diffed against.

Nobody will review this code. No teammate will ever push back on a lazy shortcut, because there is no teammate. I think that makes written constraints more necessary for solo projects, not less. A team catches your drift in review; alone, the only reviewer is a document you wrote while calm, and it only works if you wrote it before the temptation existed.

There is also a goal here a template genuinely cannot serve. This site exists to own the search results for my own name. That is an entity problem: one canonical Person, machine-readable, consistent across every page, so that a search engine has a single coherent thing to believe in. The spec treats structured data as a first-class output of every page, not an SEO garnish sprinkled on at the end. Getting that right is a data-modeling job, and data models are what design documents are for.

Code starts next week. The spec will turn out to be wrong somewhere, every spec is, but it will be wrong in specific sentences I can point at and revise. Wrong in specific sentences is the only kind of wrong you can fix.

Remiel Shirazi

CTO & Co-founder | AI, Roblox & Piano