React SPA — Edition v1¶
Edition metadata
Targets: React 19 · Vite 8 · Tailwind CSS 4 · TypeScript 6 · pnpm · Node 22+
Reviewed: 2026-07 · Next review due: 2027-07
Status: latest · Pin as: react-spa@v1
This edition captures the gold standard for the react-spa archetype as of mid-2026.
It is the rubric a scanner judges a matching repo against. Every prescription below is
written as a checkable rule so a finding can name the exact clause.
How to read a rule¶
Each rule has a stable ID (R-<AREA>-<n>), one checkable statement, the reason it exists,
and a note on how a scanner verifies it. IDs never change meaning across an edition — when
a rule is retired or its verdict flips, a new edition is cut.
Rule shape
R-AREA-n · Short imperative title
Rule. One sentence a scanner can evaluate to pass/fail.
Why. The reason — usually tied to the static, no-server constraint.
vcqa. The signal a scanner checks (a dep, a config key, a code pattern).
The rubric¶
| # | Area | Code | What it governs |
|---|---|---|---|
| 1 | Project setup | SETUP |
Vite + React + pnpm workspace, scripts, node, relative base |
| 2 | TypeScript | TS |
strict flags, project references, no any, typed boundaries |
| 3 | Structure & routing | STRUCT / ROUTE |
folders, component boundaries, routing, code splitting, SPA fallback |
| 4 | State & data | STATE / DATA |
local-first state, server-cache libs, external APIs, no own server |
| 5 | Styling | STYLE |
Tailwind v4 CSS-first, tokens, dark mode, no runtime CSS-in-JS |
| 6 | Forms | FORM |
controlled inputs, schema validation, accessible errors |
| 7 | PWA & assets | PWA |
service worker, caching, images, fonts, hashing |
| 8 | Performance | PERF |
bundle budgets, splitting, Core Web Vitals, render discipline |
| 9 | Accessibility | A11Y |
semantics, keyboard, focus, ARIA, contrast |
| 10 | Testing | TEST |
Vitest + Testing Library + Playwright, what to cover |
| 11 | Build & hosting | BUILD |
static build, base, SPA fallback, cache headers, build-time env |
| 12 | Security | SEC |
no secrets in bundle, CSP, auth via provider, dependency hygiene |
Non-negotiables¶
The rules below are the ones that, if violated, mean the repo is either broken as a static SPA or not this archetype at all. A scanner should weight these highest.
- R-DATA-1 — no private secret (API key, token, DB credential) is present in client source or the built bundle. A static SPA ships its entire source to the browser.
- R-BUILD-2 — assets load from a relative base so the app works under any path prefix / behind a proxy, not just the domain root.
- R-BUILD-3 — the host serves
index.htmlfor unknown paths (SPA fallback), or the app uses hash routing; deep links must not 404. - R-ROUTE-1 — routing is client-side only; there is no server render step.
- R-SETUP-1 — the app builds to static assets with
vite buildand needs no running server of its own to serve a request.