← Neill's Vibe
Field GuideOperating Guide · Spec Pages

The design doc nobody reads is the one that stayed a raw .md.

You finish a big push. The design that justified it is sitting in a docs/ folder as raw markdown — a wall of hashes and asterisks nobody opens twice. So you review it badly, and you can't hand it to anyone. The fix takes about a minute: turn a folder of spec files into one self-contained, tabbed web page — real headings, real tables, a status badge per doc — and pop it open in the browser. No build step, no server, one file you can forward to a lawyer, a client, or future-you.

01 · the scene

A wall of hashes in a folder you forget

Here's the loop I kept living. I'd spend real thought on a design — the spec that decides what the next feature actually is — and write it to docs/specs/whatever.md. Then review time comes and I'm squinting at ## Locked decisions and pipe-delimited table rows in a code editor, skimming the thing I most needed to read carefully. And when someone asked "what are you building?", my honest answer was a link to a markdown file that renders as a brick.

Markdown is a great storage format and a lousy review format. A table you wrote as | a | b | should look like a table when you're deciding whether to ship. The gap between those two is a one-minute tool.

02 · why render it

A page is a decision surface; a .md is an archive

The reframe that made me build this: the rendered page isn't documentation, it's the surface you make the go/no-go call on. Tables that are actually tables. Code blocks you can read. Each spec on its own tab with a Shipped / Planned / Draft badge, so a whole project's design history is one glance, not a directory listing.

And it's one file that opens anywhere. No dev server, no framework, no "npm install" for the person you send it to. That portability is the point — the same artifact works for your own review, a client sign-off, or a teammate on a plane. A path someone has to clone a repo to read is a path they won't read.

03 · the architecture

Four moves, zero dependencies in the output

The whole tool is four moves:

The one principle that makes it worth keeping: the output has no external calls. The markdown, the renderer, the styling — all baked into the one file. That's what makes it forwardable and offline-proof, and it's exactly the thing my first version got wrong.

04 · real scars

Three ways the "simple" version bit me

scar · the hotlinked renderer

V1 pulled the markdown renderer from a CDN with a <script src="https://…">. A security check flagged it instantly: hotlinking a third-party script means if that CDN is ever compromised, so is every page you handed out — and it dies the moment the reader is offline. The fix: bundle the renderer into the file. The artifact you give someone should reach out to nothing.

scar · file:// won't fetch its neighbors

Next idea: have the page fetch() the .md files sitting right next to it. Nope — open an HTML file from disk and the browser's security model blocks it from reading local files (CORS on the file:// origin). The fix: stop fetching; inline the markdown straight into the page when you generate it. One file, no neighbors required.

scar · the badge that lied

I auto-derive each tab's Shipped / Planned badge from the spec's **Status:** line — lovely, until a feature shipped and its spec file still said "planned," so the page cheerfully mislabeled a done thing as not-done. The lesson: the page is only as honest as the file. Keep your Status: lines current, or the automation will confidently tell the wrong story.

05 · make it reliable

How to keep it worth running

06 · build it by talking

Don't want to touch code? Describe it.

You don't have to write a line of this. Open Claude Code (or any agent) in a folder that has some markdown specs, paste the brief below, and it'll build the generator and run it for you. Same tool as the code section — one of you types it, the other talks it into being.


    
  
07 · the working code

Turn a folder of specs into a page tonight

One file, no installs (Node 18+). Point it at a folder of markdown and it writes a single self-contained, tabbed HTML page and opens it. The first run grabs a small markdown renderer once and caches it next to the script; after that it works fully offline, and every page it produces has zero external calls. Auto-finds ./specs, ./docs/specs, or ./docs/superpowers/specs — or pass files yourself.


    
    

Run it:
node render-specs.mjs  ·  node render-specs.mjs --specs docs/specs --title "My Project"  ·  node render-specs.mjs a.md b.md --no-open