Define the theme
Point theme tokens at the palette, keep light-dark() to colors, and avoid Core internals.Map the palette to tokens
A theme token is a named slot that Astryx components read for a value — --color-accent for the accent color, and so on. Components never read your palette directly; they read tokens. Defining a theme means pointing each token at a palette shade, so the components wear your colors.
Import the palette in oceanTheme.ts and point your tokens at its stops. Each token takes a [light, dark] pair — the shade to use in light mode and the one in dark mode.
ts// themes/ocean/oceanTheme.tsimport {defineTheme} from '@astryxdesign/core/theme';import {palette} from './tokens/ocean.palette';const {light, dark} = palette.ocean;export const oceanTheme = defineTheme({name: 'ocean',tokens: {'--color-accent': [light['45'], dark['70']],},});
Local imports must stay inside the theme folder. One that leaves it, such as ../../shared/colors, fails with invalid_theme, and the theme disappears from theme list. npx astryx theme template writes a file that explains every defineTheme field. For the full token set, scope selectors, and component theming, read astryx docs theme.
Build on another theme
To base a theme on an existing one, extends it: import the base theme and override only the tokens you change. The derived theme keeps a live link to the base and inherits its later changes — unlike --from, which forks a copy (astryx docs cli/integrations/building-blocks/themes/add-a-theme).
tsimport {defineTheme} from '@astryxdesign/core/theme';import {oceanTheme} from './oceanTheme';export const oceanContrastTheme = defineTheme({name: 'ocean-contrast',extends: oceanTheme,tokens: {'--color-accent': ['#0051a3', '#4aa3ff'],},});
Keep light-dark() to colors
Each [light, dark] pair compiles to a light-dark() value, which switches only colors. Give it colors. For a value that is not a plain color — a gradient — put light-dark() on each color stop, not around the whole value: a browser without light-dark() drops the declaration, and the stop form is the one that degrades safely.
Do not set Core private variables
Core private variables start with --_, such as --_field-radius. They are internals and can change in any Core release, so theme build reports each one it finds as an [error]. Set the standard CSS property instead — borderRadius, padding — and let the build emit the internal variable where Core needs it.
Declare the peer dependencies
The theme imports @astryxdesign/core/theme, so declare Core as a peer dependency, with the range of Core versions you test the theme against — a range, not an exact version, so a Core patch release does not force a republish. integration add theme already declared the optional @astryxdesign/cli peer that reads themes:
json"peerDependencies": {"@astryxdesign/core": "^0.7.0","@astryxdesign/cli": ">=0.7.0"},"peerDependenciesMeta": {"@astryxdesign/cli": {"optional": true}}