How Unit modules are built
Six binding standards govern every Unit module. This guide is the practical layer — how each standard applies in daily work, what "done" means, what's forbidden, and what reviewers check.
Engineering StandardEach rule maps to a failure mode we've already paid for
Unit standards are not aspirational. They are the corrective response to specific past incidents — and the cheapest way to prevent the next one.
One library, six binding standards
Every module satisfies all six. Click any card for the practical details and the binding markdown source.
Unit Design System
- Color tokens, typography, spacing, elevation
- Component visual discipline
- No raw hex outside
:root
Preview System
- Self-contained preview HTML
- Deterministic mock states; no async
- Reproducible screenshots
Test System
- Pure-logic unit tests
- Browser smoke + capture pipelines
- Forbidden-state absence assertions
Traceability
- Authority chain at the top of binding docs
- Author history rows on every spec
- No silent changes
State Modeling
- Closed lifecycle states (no invented states)
- Validation states disjoint from terminal failures
- Forbidden post-submit causes named explicitly
UI Copy
- No raw backend enums in user UI
- Safe error language with
userFacingReason - No technical leakage (extrinsic, GraphQL, OCW)
One direction. Spec leads. Reports follow.
Each artifact derives from the one to its left. Reversing the flow ("the code says so, update the spec") is a drift signal — fix the spec before the code lands.
Done is a verification, not a feeling
Common false-done signals
- "The screen renders without errors."
- "The happy path works on my machine."
- "The TSX type-checks."
- "I tested it manually, the tests are coming next."
- "Spec is rough, I'll write it after."
Done means all of this
- UI matches the binding spec
- Preview works end-to-end with zero console errors
- Tests pass and assert invariants explicitly
- Screenshots exist for every reviewable state
- STATUS / completion report carries this pass
- Forbidden states / patterns asserted absent
- No unrelated modules touched
The non-negotiable list
These patterns must not appear in any module. If a need arises, the spec changes first — the implementation never leads.
userFacingReason; never surface DepositNotPending, TX_REUSED, etc. to end users.
toFixed() must never be reused as the executable amount.
fetch(), no async.
The nine questions every review must answer
Date.now, no Math.random, no network)?