Skip to content
→ All work

Case study 32 / 37

Statuscraft

A status page generator that refuses to lie: every status, badge and incident is computed from an append-only log of real synthetic-check results.

Status
In development
Period
2026
Domain
Cloud · Web
Language
TypeScript
Last push
26 OCT 2026
License
MIT
Source of claims
README.md, CHANGELOG.md, src/cli.ts, src/checker/statusEngine.ts, test/honesty.test.ts, .github/workflows/ci.yml; quickstart run from a fresh clone 2026-10-25
statuscraft status page, dark theme, with uptime bars for four services

01/The problem

Hosted status pages let someone click “all systems operational” during an outage, and static templates are hand-edited on deploy. Neither checks anything.

02/The system

A TypeScript CLI that runs HTTP checks with assertions, appends every observation to a JSONL log, derives incidents from consecutive bad runs, and generates a static dark/light page from that history alone. There is no admin switch for “operational”; missing or stale data is never shown as green.

Data flow (README)6 components
  • Config to Checker
  • Checker to results.jsonl
  • results.jsonl to buildSiteData
  • incidents.json to buildSiteData
  • buildSiteData to Static site

03/Implementation

  1. 01A checker calls each endpoint on a schedule and evaluates assertions: status code or range, latency thresholds, body text or regex, JSON paths and headers.
  2. 02Every observation, pass or fail, is appended, never edited, to a JSONL file that serves as the audit trail and can be replayed through the generator.
  3. 03Incidents are derived from runs of consecutive degraded or down results; a postmortem overlay can add a title and text but cannot invent an incident.
  4. 04The generator is a pure function from config, results and overlay to a static index.html, CSS and theme script, plus a data.json audit snapshot.

04/Engineering

Only latency can be “degraded”

A failing non-latency assertion is always down; latency between the degraded and down thresholds, with everything else passing, is degraded. The rule lives in one file.

Missing and stale data are never green

A service with no results shows “No data yet”, one older than staleAfterMinutes shows “No recent data”, and future-dated or malformed rows are skipped and counted. A dedicated regression suite enforces this.

Pure, synchronous generation

buildSiteData takes hand-built result arrays in tests, so page output is reproducible without running real HTTP checks.

05/Interface

The generated Northwind demo status page in dark theme, with 90-day uptime bars per service and derived incident history.
The same generated status page in light theme.
The generated status page on a phone, in dark theme.

Real screenshots of the running software. Captions state the data shown.

06/Tech stack

  • TypeScript
  • Node.js 20+
  • Commander
  • Zod
  • Vitest
  • ESLint
  • GitHub Actions

07/Result

Verified outcomes

  • 145 Vitest tests and strict type-checking, run by CI on Ubuntu, Windows and macOS together with lint, build and a full demo-site build (per the README).
  • The README screenshots are the output of a seeded, deterministic demo fixture checked into the repository.

Known limitations

  • Not published to npm; it runs from a clone.
  • Checks are HTTP only.

08/Links

Related work

Next case study

ModelHarbor →