The stack, tooling, and workflow behind this site are not chosen for novelty. Each decision has a concrete reason.
Monorepo with pnpm workspaces. The repository uses a pnpm workspace with a single apps/web package today, structured to accommodate additional packages (API services, shared libraries, CLI tools) without restructuring. pnpm's strict dependency isolation means a phantom dependency that works locally but fails in CI is caught before it ships, not after. This is a small overhead during setup and a large saving during debugging.
Typed end to end. TypeScript is configured in strict mode across the entire codebase. External API responses are validated with Zod at the boundary and typed from that point forward — the rest of the application never handles unknown or any shapes. When the Open-Meteo schema changes or an IP provider adds a field, the Zod schema is the single place that change is handled. Everything downstream benefits automatically.
Testing as a layered investment. Vitest covers the unit layer today: WMO code mapping, AQI classification, IP range detection, UA parsing, fingerprint collectors. Playwright e2e is the next addition — full page renders, sitemap and robots delivery, 404 behaviour, and the core interaction flows for each tool. The split is intentional: unit tests run in milliseconds and give fast feedback during development; e2e tests catch integration issues that unit tests cannot see, and they run against a production build to be honest about ship-readiness.
CI that blocks on quality. Every pull request runs the pipeline: type check, lint, unit tests, content-readiness checks, and a production build. A type error or a failing test blocks the merge. The pipeline runs on GitHub Actions. There is no manual QA step — if CI passes, the build is considered shippable. This only works if the tests are written to actually catch regressions, which is why the suite covers the golden path and the failure cases, not just the happy path.
Accessibility as a gate, not a retrospective. WCAG 2.1 AA compliance is a promotion criterion, not a polish pass. Keyboard navigation, focus management, screen reader labels, and colour contrast are addressed during implementation. Tools that do not meet this bar do not leave /lab. The practical reason is that fixing accessibility after the fact is significantly more expensive than building it in — the same is true of privacy and security.
The promotion model. Every tool starts at /lab. Promotion to a homepage slot requires three things: the tool solves a problem I would actually use it for, the code is readable without a lengthy explanation, and it passes the accessibility and privacy gates described above. Visual polish and feature completeness are not requirements for promotion — they iterate after launch. The border between "prototype" and "production" is engineering quality, not UI finish.
Why this workflow on a personal project. The same practices that prevent production incidents on a team of ten are the practices that make solo projects maintainable six months later. CI, strict types, schema validation, and a defined promotion process exist here for the same reason they exist in any production environment: they reduce the cost of change and the cost of mistakes.