Skip to content
← Back to Blog

This projects page is a build artifact

·4 min read·Updated

My /projects page makes three kinds of claims: “104 public repos.” “Copy this command and run it.” “17 of 18 curated repos pushed in the last 30 days.” All three rot. Star counts age, install commands break, and I would not notice either one, because I am not in the habit of re-reading my own website. So the page stores none of these numbers. It computes them.

Here is how.

What I write vs. what GitHub says

Everything I typed myself — descriptions, topics, install commands — lives in a data file and gets reviewed like code. Everything GitHub owns — stars, forks, last-push dates — is never typed anywhere. At build time, every project is resolved: live API cache if it is fresh, committed snapshot if it is not. If a curated repo is in neither, the build fails. Doesn’t render a zero, doesn’t warn. Fails. I would rather fix a red build than explain a zero to someone who spotted it before I did.

The committed snapshot is itself generated. pnpm run snapshot:refresh hits the API once, regenerates the snapshot module and the full-repo archive, and snapshot:check diffs both against the live API — so drift shows up in my terminal instead of in a screenshot somebody else took of my page.

Every install command is executed

The page’s core promise is “copy this and run it.” That is only a promise if I ran it first. So every install line was executed in a sandbox with empty GOCACHE and GOMODCACHE — no warm caches, the same state as your laptop when you paste.

Two failed.

  1. go install github.com/larsartmann/dynamic-markdown-site/cmd/dynamic-markdown-site@latest: the repo ships templates/layout.templ without the generated Go file, so the templates package does not exist — at the tagged release or on the default branch. The install line is gone from the page. It comes back when a release actually installs.

  2. gogenfilter looked uninstallable for weeks because its module path is github.com/LarsArtmann/gogenfilter/v3 — capital letters. The module proxy resolves case-insensitively, so everything looked fine until go get insisted on exact case. Weeks of “why won’t this install” over letters that differ only in size. The working command is on the page now, capitals and all.

Both bugs are mine. That is exactly why I wanted a machine to find them for me.

Fifteen commands passed. Each carries the exact module path from the repo’s own go.mod, including the /v2-style suffixes that quietly break copy-pasted paths.

The archive: every repo, forks included

Below the eighteen curated cards sits a collapsed table of every public repository — forks marked as forks, push dates shown, nothing curated out. Same table, same order the API returns. Tests pin it: one row per public repo, unique names, every curated repo present.

If my curation looks like cherry-picking to you, scroll down and check. The forks are right there.

Screenshots do not catch overflow

The nastiest bug this page ever had was invisible in every screenshot I took: a wide install command pushed its max-content width through a CSS subgrid and stretched the card grid to 1477px on a 1440px viewport. body { overflow-x: clip } had already eaten the scrollbar, so the page looked perfect while a third of it hung off-screen. I found it by measuring, not by looking.

So now the page gets measured. One gate loads every built route at 390, 768, and 1440 pixels and fails when document.scrollWidth beats the viewport. Another clicks every copy button in headless Chromium, EN and DE, and asserts the exact command lands on the clipboard. A third walks the page with nothing but Tab presses. Anything that can break quietly now breaks my build instead.

What that buys

The numbers cannot rot silently — a stale snapshot fails a freshness gate. The commands cannot break silently — the sandbox run catches it. And nothing is on the page because it sounded good. It is the same standard I hold client systems to: if it matters, the build checks it; if the build cannot check it, it does not ship.

The projects page is the smallest system I own end to end, which makes it the cheapest place to keep that standard.

Go copy an install command and run it. That is what all of this is for.