Use a theme
Apply a theme to your app: wrap in a provider, pick a theme, switch dark mode, nest themes, and choose runtime or built for production.Wrap your app in a theme
bashnpm install @astryxdesign/theme-neutral
tsximport {Theme} from '@astryxdesign/core';import {neutralTheme} from '@astryxdesign/theme-neutral';function App() {return (<Theme theme={neutralTheme}><YourApp /></Theme>);}
tsximport {Theme} from '@astryxdesign/core';import {neutralTheme} from '@astryxdesign/theme-neutral/built';import '@astryxdesign/theme-neutral/theme.css';function App() {return (<Theme theme={neutralTheme}><YourApp /></Theme>);}
Each theme ships as its own npm package. Install the one you want, then wrap your app in <Theme>. The same pattern works for every theme; just swap the package and import name.
The default import uses runtime style injection, which works everywhere with no build step. The /built import skips injection and relies on the pre-compiled CSS file for better performance and SSR support.
Available Themes
Install the theme package you want with npm install @astryxdesign/theme-{name}, then import its theme object as shown below.
| Theme | Import | Description |
|---|---|---|
| Neutral | import {neutralTheme} from '@astryxdesign/theme-neutral' | Muted, minimal aesthetic with Figtree typography. A good starting point. |
| Butter | import {butterTheme} from '@astryxdesign/theme-butter' | Golden, buttery surfaces with blue accents; Sarina + Outfit type. |
| Chocolate | import {chocolateTheme} from '@astryxdesign/theme-chocolate' | Warm brown tones and cozy beige; Fraunces + Albert Sans type. |
| Gothic | import {gothicTheme} from '@astryxdesign/theme-gothic' | Dark-only atmospheric theme; deep blue-gray surfaces, distressed display type. |
| Matcha | import {matchaTheme} from '@astryxdesign/theme-matcha' | Earthy greens; DM Sans + Playwrite US Trad type. |
| Stone | import {stoneTheme} from '@astryxdesign/theme-stone' | Warm stone and slate tones; Montserrat + Figtree type. |
| Y2K | import {y2kTheme} from '@astryxdesign/theme-y2k' | Playful Y2K pop; periwinkle body, holographic accents, Poppins + Crimson Text. |
All theme packages export from two subpaths:
- @astryxdesign/theme-{name}: source theme (runtime injection)
- @astryxdesign/theme-{name}/built: pre-built theme (pair with theme.css)
Theme Props
<Theme> takes theme (required), mode ('system' by default, or 'light'/'dark'), and children. For every prop, run astryx component Theme.
Using a Theme from an Integration
Install the integration as a direct dependency and Astryx discovers its source themes and guide topics without an astryx.config file. Install Core too because the copied source imports defineTheme from @astryxdesign/core/theme.
bashnpm install @astryxdesign/core @acme/brand-integrationastryx theme list --package @acme/brand-integrationastryx docs brand-themeastryx theme add ocean --package @acme/brand-integrationastryx theme build src/themes/ocean/oceanTheme.ts
The copy is editable project source, not a reference back into node_modules. The complete theme directory comes with it, including its typed .doc.mjs, nested token and palette modules, and receipts. A second add refuses to overwrite those files unless you pass --overwrite.
Dark mode
Use [light, dark] tuples in token values for automatic mode switching. Use mode='system' (default) on Theme to follow OS preference.
tsx'--color-accent': ['#0064E0', '#2694FE'],// ^light ^dark
tsxconst [mode, setMode] = useState<'light' | 'dark'>('light');<Theme theme={myTheme} mode={mode}><Buttonlabel={mode === 'light' ? 'Switch to Dark' : 'Switch to Light'}onClick={() => setMode(m => (m === 'light' ? 'dark' : 'light'))}/></Theme>;
To create a theme with custom dark mode colors, see astryx docs author-a-theme.
Nested themes
Wrap different sections in separate <Theme> providers.
tsx<Theme theme={lightTheme} mode="light"><Layoutheader={<LayoutHeader>...</LayoutHeader>}start={<Theme theme={darkTheme} mode="dark"><LayoutPanel>{/* Dark sidebar */}</LayoutPanel></Theme>}content={<LayoutContent>{/* Light content */}</LayoutContent>}/></Theme>
Runtime vs Built Themes
Themes work in two modes:
| Runtime (source) | Built | |
|---|---|---|
| Import (published theme) | @astryxdesign/theme-{name} | @astryxdesign/theme-{name}/built + theme.css |
| Import (custom theme) | defineTheme() directly | Built .js + .css from astryx theme build |
| How it works | useInsertionEffect injects <style> at hydration | Pre-compiled .css file loaded with the page |
| Component overrides | Injected client-only | In static CSS: present during SSR |
| SSR safe | Tokens yes, component overrides flash on hydration | Fully SSR safe: no flash |
| Best for | Dev, prototyping, client-only SPAs | Production, SSR apps (Next.js, Remix) |
| Guidance | Practices |
|---|---|
| Do | Use the /built subpath + theme.css for production SSR apps. |
| Do | Use runtime themes during development for fast iteration. |
| Do | Run |
| Don't | Use runtime themes in production SSR apps; component overrides will flash on hydration. |
| Don't | Import /built without the CSS file; component overrides won't apply. |
To build a custom theme for production, see the Build section of astryx docs author-a-theme.