ADR 0021: Central `lib/fonts.ts` font registry
ADR 0021: Central lib/fonts.ts font registry
Section titled “ADR 0021: Central lib/fonts.ts font registry”- Status: Accepted
- Date: 2026-04-21
- Deciders: Ideony team
Context
Section titled “Context”Font-family strings were duplicated across ~280 call sites in the mobile app (40+ files). Ad-hoc per-file edits to hyphenated-suffix Switzer/Gambarino names were error-prone, violated DRY, and risked drift from the families actually loaded in app/_layout.tsx. Several bare strings ("Switzer", "Gambarino") shipped without the suffix required for native rendering.
Decision
Section titled “Decision”Introduce apps/mobile/lib/fonts.ts — a single typed fonts const exporting the canonical font-family names matching _layout.tsx’s useFonts() registry. All fontFamily: references must import fonts from there; no raw strings. Typed so TypeScript catches typos.
export const fonts = { display: "Gambarino-Regular", thin: "Switzer-Thin", light: "Switzer-Light", regular: "Switzer-Regular", medium: "Switzer-Medium", semibold: "Switzer-Semibold", bold: "Switzer-Bold", extrabold: "Switzer-Extrabold", black: "Switzer-Black",} as const;Home screens (6 files) migrated as exemplar. Remainder migrates on touch.
Consequences
Section titled “Consequences”- Single source of truth — renaming a font family is a 1-line change
- TypeScript catches typos at compile time (typed
FontKey) - Matches loaded families from
_layout.tsx— no more silent native fallback on missing suffix - Docs pattern: ban raw strings in
../design-system.md− Existing ~270 call sites still use raw strings until touched (acceptable — migrate-on-touch) − Minor import overhead per component file
Alternatives considered
Section titled “Alternatives considered”- Tailwind-only (
font-mediumclassName) — works in NativeWind but breaks inlinestyle={{fontFamily: ...}}patterns already pervasive; mixed model was worse than unifying on const reference. - Per-file hyphenated-suffix codemod (the path being walked when user intervened) — initial approach; abandoned after user correctly flagged DRY/KISS violation. Would have touched 40+ files, no abstraction.
- Extend
packages/design-tokens/src/index.ts— considered butfontsis mobile-specific (native font-family strings) and shouldn’t leak into shared types; kept tokens package pure.
Related
Section titled “Related”- Supersedes per-file font-family string convention (no ADR — was de-facto).
- Reinforced by
design-system.mdhard-ban: “No raw font-family strings — always import from@/lib/fonts”. - Commit:
0c8182b(shipped 2026-04-21).