Design Tokens
Every color, radius, shadow, and font in ShockStack comes from one source: the Style Dictionary pipeline in packages/tokens. Tokens are consumed by Tailwind 4, Astro components, and Vue islands through generated CSS custom properties.
If it’s a visual value in the product, it almost certainly lives as a token.
The pipeline at a glance
- Edit — author token values in
packages/tokens/tokens/*.json(DTCG format). - Build —
pnpm tokens:buildruns Style Dictionary and emits CSS, JSON, and a Tailwind preset. - Consume — the frontend imports
tokens.cssinsrc/styles/global.cssand exposes semantic utilities (bg-bg-primary,text-fg-muted,border-border-default,text-accent-purple, …).
Rebuilding tokens
Build tokens
$ pnpm tokens:build
✔ wrote packages/tokens/dist/tokens.css
✔ wrote packages/tokens/dist/tokens.js
✔ wrote packages/tokens/dist/tailwind.tokens.js
% pnpm tokens:build
✔ wrote packages/tokens/dist/tokens.css
✔ wrote packages/tokens/dist/tokens.js
✔ wrote packages/tokens/dist/tailwind.tokens.js
PS C:\> pnpm tokens:build
✔ wrote packages/tokens/dist/tokens.css
✔ wrote packages/tokens/dist/tokens.js
✔ wrote packages/tokens/dist/tailwind.tokens.js
The build emits:
dist/tokens.css— all themes, each scoped under[data-theme="<name>"].dist/tokens.js+dist/tokens.d.ts— typed constants for runtime use.dist/tailwind.tokens.js— a Tailwind preset mapped to semantic names.
Tokens are prebuilt for the frontend
The frontend imports ../../packages/tokens/dist/tokens.css directly. If you bump
token values without rebuilding, the app won’t pick up the change. Run pnpm tokens:build
(or start the repo with ss dev, which chains it for you).
Token categories
The frontend exposes these semantic groups via Tailwind (@theme block in frontend/src/styles/global.css):
| Group | Tailwind classes | Use for |
|---|---|---|
| Backgrounds | bg-bg-primary, bg-bg-secondary, bg-bg-tertiary | App chrome, cards, overlays |
| Foregrounds | text-fg-primary, text-fg-secondary, text-fg-muted | Headings, body, captions |
| Accents | text-accent-{purple,pink,cyan,green,orange,yellow,red} | Brand, status, callouts |
| Borders | border-border-default, border-border-muted | Cards, dividers |
| Selection | bg-selection | Text selection highlight |
| Radii | rounded-{sm,md,lg,xl,2xl,full} | Corner radius |
| Shadows | shadow-{sm,md,lg,xl} | Elevation |
Prefer these over one-off hex codes — they are the only values that respond to theme changes.
Authoring tokens
Token sources live in packages/tokens/tokens/:
base.json— primitives that rarely change.custom.json— project-specific overrides.dracula.json,nord.json,tokyo-night.json,dawn.json,midnight.json,gruvbox*.json,catppuccin-mocha.json,one-dark.json,solarized-*.json,kanagawa-wave.json,rose-pine-moon.json,everforest-dark.json,ayu-mirage.json,github-dark-dimmed.json— built-in themes.design-md.json— generated output ofpnpm tokens:extract(see below).
Each theme exports the same semantic keys; only the underlying values change. That contract is what makes theme switching truly drop-in.
Extracting tokens from DESIGN.md
ShockStack supports the @google/design.md workflow. Designers can author a single Markdown spec in docs/system/DESIGN.md; pnpm --filter @shockstack/tokens tokens:extract converts that spec into tokens/design-md.json, which flows through the same Style Dictionary build.
pnpm --filter @shockstack/tokens tokens:extract
pnpm tokens:build
This is optional — you can author JSON directly. Use whichever fits your team.
Customization workflow
- Edit
packages/tokens/tokens/<file>.json(orDESIGN.md, then extract). - Run
pnpm tokens:build. - Check the app visually across at least two themes (e.g.
midnightanddawn). - Commit both the source tokens and the regenerated
dist/files — generated output is tracked so deploys don’t need to rebuild tokens.
What not to do
- Don’t add raw hex codes in components. If you need a new value, add a token.
- Don’t edit
dist/files by hand. They are regenerated on every build. - Don’t couple to a single theme. If a component only looks right in dark mode, the token assignment is wrong.
See also
- Theming — the 19 built-in themes and how switching works.
- Component library — components that already consume these tokens.