Architecture
How Stareezy UI is organized as a monorepo with strict dependency boundaries.
Package structure
stareezy-ui/
├── packages/
│ ├── tokens/ # Token definitions, theme system, t accessor, createUi
│ ├── core/ # Utilities, hooks, platform helpers
│ ├── runtime/ # O(1) style registry and platform adapters
│ ├── stylesheet/ # Atomic CSS sheet management (web)
│ ├── compiler/ # Babel/Vite/Metro build-time transform
│ └── components/ # 17+ cross-platform components
└── apps/
├── docs/ # This documentation site (Next.js)
├── storybook/ # Component stories (Storybook 8)
└── playground/ # Live code editorBuild order
Packages must be built in dependency order. The pnpm run build script handles this automatically:
tokens → core / stylesheet → runtime → compiler → componentsPackage responsibilities
@stareezy-ui/tokensToken factory, all token definitions, theme system (ThemeProvider, useTheme, useThemeSwitch), t accessor, ThemeToken, createUi, module augmentation. Zero dependencies.
@stareezy-ui/coreShared utilities, platform detection, hooks (useDeviceLayout, useDocsTheme), string/date/currency utils.
@stareezy-ui/stylesheetAtomic CSS sheet management — injects :root variables, deduplicates rules, handles theme switching via data-theme.
@stareezy-ui/runtimeO(1) style registry. resolve(token) is a single Map.get(). Web adapter returns CSS class names; RN adapter returns StyleSheet IDs.
@stareezy-ui/compilerBabel/Vite/Metro plugin. Reads stareezy.config.ts, extracts Token props at build time, emits atomic CSS. ThemeToken props are not extracted — they resolve at runtime.
@stareezy-ui/components17+ cross-platform components. Box accepts Token<T>, ThemeToken, and plain values. Custom shorthands from SzrCustomConfig are typed via module augmentation.
Token flow
Two token types
There are two distinct token types in Stareezy UI — understanding the difference is key:
// Token<T> — static, always the same value
import { colors } from '@stareezy-ui/tokens'
colors.celurenBlue[500]
// { __token: true, id: "celurenBlue-500", value: "#024CCE" }
// → Extracted by compiler, resolved to CSS class at build time
// ThemeToken — dynamic, resolves to current theme's value at render time
import { t } from '@stareezy-ui/tokens'
t.text.primary
// { __themeToken: true, path: "text.primary" }
// → NOT extracted by compiler, resolved via useTheme() at render time
// → aurora: "#f0f0f8", dark: "#f0f6fc", steins-gate: "#e8dcc8"Module augmentation
Custom shorthands from createUi() flow into BoxProps via TypeScript module augmentation:
// stareezy.config.ts
declare module '@stareezy-ui/tokens' {
interface SzrCustomConfig extends typeof ui {}
}
// Now BoxProps includes your shorthands:
<Box br={12} f={1} /> // ✅ typed — br → borderRadius, f → flexAtomic CSS strategy
Each token maps to exactly one CSS class. Theme switching requires zero JavaScript re-renders on web:
.sz-celurenBlue-500 { background-color: var(--celurenBlue-500); }
/* Theme override — only a data-theme attribute change needed */
[data-theme="aurora"] { --celurenBlue-500: #00ff88; }
[data-theme="steins-gate"] { --celurenBlue-500: #4a9eff; }
[data-theme="light"] { --celurenBlue-500: #024cce; }packages/tokens package has zero runtime dependencies — no React, no React Native, no UI framework. It can be used in any JavaScript environment including Node.js scripts and CDN bundles.Tree shaking
Every token category lives in its own file. Importing colors does not pull in spacing, radius, or typography. The compiler's dead-code elimination removes any tokens not referenced in your component tree.