Skip to main content
Lightning Jar - Web Studio Lightning Jar Wordmark

The Website Workbench: Every Check We Run, and What Each One Caught

7/28/2026
The Website Workbench: Every Check We Run, and What Each One Caught

The Website Workbench: Every Check We Run, and What Each One Caught

Series note: This is the toolbox half of a pair. The thesis half argues that a website is a system you operate, not an artifact you finish. This half is the workbench: every automated check we run on website projects, what it costs (spoiler: nothing), and a real defect each one caught on our own site recently. Nothing here is hypothetical.

The list is organized by how often each check runs: on every change, on every publish, and on a schedule. The order matters. Checks that run constantly have to be fast and silent when things are fine; checks that run weekly can afford to be thorough and chatty.

Layer one: gates on every change

These run in seconds, locally and in CI, and a failure blocks the commit. Their job is to make categories of decay impossible rather than merely detected.

Strict TypeScript, checked all the way into templates. svelte-check extends type checking into component markup, which is where web bugs actually live. What it caught this week: a sitemap search feature we added assumed every entry had an href and title; the type checker knew some sections declared them optional, and the fix happened before the page ever rendered undefined. Zero errors is a merge condition, not an aspiration.

One tool for formatting and linting. We use Biome: one config, one fast pass, no prettier-versus-eslint arbitration. The win is not any single rule. It is that style stops being a discussion and diffs stop containing noise, which makes every other review sharper.

Dead-code scanning. fallow walks the repository for exports nothing imports, dependencies nothing uses, and duplicated code. Websites accumulate dead weight at a remarkable rate: the component someone replaced but did not delete, the helper that outlived its caller. Dead code is not neutral; it is where the next developer, human or agent, wastes context and confidence.

Tests, with characterization tests doing the heavy lifting. Unit tests earn their keep, but the workhorses on a content site are characterization tests: our markdown parser is pinned against a frozen corpus of published articles with content hashes, so a parser upgrade that would silently reformat years of writing fails a test instead. The same pattern pins our RFC 9727 API catalog: the machine-readable endpoint list has a test asserting its exact shape, so the catalog cannot silently shrink when someone refactors. When silent change is the failure mode, byte-equality is the test. The same layer carries route-level behavioral tests where the stakes justify them: on our most security-conscious client work, the content negotiation, the CSP nonce plumbing, and the subresource integrity hashes each have tests of their own, because a security header that silently stops applying is exactly as invisible as a reformatted archive.

Environment variables as a committed contract. Varlock keeps the schema of required env vars in the repository with the values elsewhere, so a missing or malformed variable fails the build with a named error instead of failing at runtime with a mystery. Configuration drift is a deploy-time problem; catch it at deploy time.

Layer two: gates on publishing

Content is a deploy. It changes what users see, it can break layouts, and it carries your voice. It deserves gates of its own.

Editorial Pattern Scans. We keep a grep-able pattern file of writing tells we do not want in published prose, from house-style rules to the stock phrases that mark machine-drafted text, and every article gets scanned before it publishes. The irony is deliberate: some of our conent is AI-assisted, and the assistance should never be detectable as a style. A pattern file plus review of every hit in context is a five-minute gate.

Frontmatter Contracts. Our CMS validates article metadata against a per-collection schema at save time: required fields, canonical tag names, structural shape. What it caught this week: a draft staged with a tag casing that did not match the site's canonical list, and a missing required image, both flagged at staging rather than discovered as a broken card on the live index page.

Layer three: audits on a schedule

These are the checks that used to be consulting engagements. Each one below now lives in our repository as a small harness that re-runs with one command, and each earned its place by finding real defects on a site we had every reason to believe was in good shape.

Accessibility: axe-core over every template. Not a spot check of the homepage: a script drives a headless browser through all 26 of our page templates and runs the axe rules engine on each. The first full sweep found 10 distinct rule failures we did not know we had, including duplicate landmark roles on nearly every page, a 404 page with no title element, white-on-blue table cells at a 3.6:1 contrast ratio, and horizontally scrollable charts a keyboard could never reach. Two commits later: zero violations on all 26 templates, and the conventions that fixed it are now enforced by the build, so a future page cannot quietly regress. Given that the 2026 WebAIM Million found detectable failures on 95.9% of the top million home pages, the odds your site has some are excellent, and the sweep that finds them is an afternoon.

Performance: Lighthouse under honest conditions. Simulated mobile, against production, over every template, because numbers measured on a developer machine describe nobody's real visit. Our worst page scored 74, and the diagnosis was not what we would have guessed: nearly all the lost points were layout shift from web font swaps, plus a lazy-loading attribute on the exact image the score is computed from. The fixes were cheap once measured: metric-matched fallback fonts, preloading three font files, priority hints on above-the-fold images, reserved space for hero images. Every audited page now scores 86 to 94. The lesson we keep relearning: measure before fixing, because the bottleneck is reliably not where intuition points.

SEO: the floor check, plus the crawl no per-page tool can do. Lighthouse also scores an SEO category, and it is worth being honest about what it is: a crawlability floor covering titles, meta descriptions, canonicals, robots directives, and valid structured data, with nothing to say about content, keywords, or links. Run it anyway; the floor is cheap to pass and embarrassing to fail. Our sweep scored 100 on 23 of 24 templates, with one missing meta description as the whole haul. The more interesting check is the one per-page tools cannot do: a script that crawls every URL in the sitemap, all 249 pages in our case, and compares them, hunting duplicate titles, duplicate descriptions, and missing canonicals across the whole site. Ours came back clean on all three, and then found something better: one page returning 403 to every visitor, search crawlers included, because a firewall rule matched more of the URL space than intended. An SEO audit is also an availability audit. A page nobody can fetch does not have a ranking problem; it has an existence problem, and nothing inside the page can tell you about it.

Agent Readiness: the newest audit on the bench. More than half of HTML page requests now come from automated clients, and they read a different surface than humans do: llms.txt, structured feeds, MCP endpoints, API catalogs, markdown content negotiation. Scanners now grade this the way Lighthouse grades performance. Working through one took our site from mostly invisible to agents to 10 of 11 findings closed; the full write-up is its own article. If agents matter to your traffic, and the numbers say they already do, this is the audit most sites have not run yet.

Cost and Health Monitoring: tuned to fail loudly. The most expensive defects we found all year produced no error at all: an automated client that was 85% of a Google Maps bill, and a translation backend that was dead for two weeks behind a graceful cache. Both taught the same rule: anything that fails open needs a health signal that does not depend on the output looking wrong. Concretely, that means billing alerts set just above normal spend, an error tracker (we use Sentry) whose alert copy states the consequence rather than the mechanism, so the one alert that matters doesn't read like the fifty that don't, and analytics read as a diagnostic instrument rather than a scoreboard. We use Plausible, and it earns its keep: the maps discovery above started as an analytics segment showing 153 page views per "visitor." Monitoring is an audit that runs while you sleep.

The bill

Tally the tools above: TypeScript, svelte-check, Biome, fallow, a test runner (Bun on this site, Vitest with Storybook on client work), Varlock, grep, axe-core, Playwright, Lighthouse. Every one is free and open source. The two paid tools in the kit are the watchers, Sentry and Plausible, and together they cost less per month than a single billable hour. The kit flexes at the edges per project, a tag manager beside the analytics here, compliance-driven security tests there, but the three layers never change. The harnesses around everything are a few hundred lines, written once. The historic cost of this list was never licensing; it was skilled attention, and that is exactly what coding agents now supply for the repetitive middle of the work: running the sweep, reading the failures, applying the mechanical fixes, re-running to prove it. The judgment stays human. The toil does not.

Which is why the conclusion of the companion article bears repeating from the workbench side: the standard this tooling enforces used to be a budget line, and it is now a habit. The only expensive thing left is not knowing.

headshot of Kevin Peckham
Kevin Peckham
Principal, Lightning Jar