How to Create a Custom Theme in Astryx Using Provided Packages
Create a custom Astryx theme by defining design tokens with stylex.createTheme in a dedicated package, wrapping them in a ThemeProvider component, and mounting the provider at your application's root to inject the theme context throughout the component tree.
Astryx is Meta's open-source design system framework that uses StyleX for compile-time CSS optimization. Creating a custom theme involves extending the core theming utilities to define your own CSS custom properties and design tokens. This process mirrors the implementation found in Astryx's built-in themes like y2k and gothic, which reside in the packages/themes directory.
Define Theme Tokens in a StyleX File
In Astryx, themes are defined using StyleX's createTheme API. Create a new file (conventionally named tokens.stylex.ts) within your theme package to declare all design tokens as CSS custom properties.
import { stylex } from '@stylexjs/stylex';
export const myCustomTokens = stylex.createTheme({
colorPrimary: 'var(--my-color-primary)',
colorBackground: 'var(--my-color-bg)',
spacingSmall: '4px',
spacingMedium: '8px',
fontFamilyBase: 'system-ui, sans-serif',
});
This pattern aligns with the token definitions found in packages/themes/y2k/src/y2kTheme.ts, where each theme exports a consistent set of variables mapped to CSS custom properties.
Create the ThemeProvider Component
After defining tokens, export a React provider that injects the theme into the StyleX context. This component wraps @stylexjs/stylex's ThemeProvider and passes your custom token object.
import React from 'react';
import { ThemeProvider as StylexProvider } from '@stylexjs/stylex';
import { myCustomTokens } from './tokens.stylex';
export const MyThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => (
<StylexProvider theme={myCustomTokens}>
{children}
</StylexProvider>
);
According to the Astryx source code in packages/core/src/theme/, the ThemeProvider pattern is the standard mechanism for distributing theme values to child components via React context.
Apply the Theme at the Application Root
Mount your custom provider at the root of your React application to ensure all child components can access the theme tokens.
import React from 'react';
import ReactDOM from 'react-dom/client';
import { MyThemeProvider } from '@my-org/my-theme';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
<MyThemeProvider>
<App />
</MyThemeProvider>
);
Once wrapped, components can consume the theme using the useTheme hook from @astryxdesign/core or directly via stylex.props, as implemented in packages/core/src/theme/useTheme.ts.
Reference Implementation: Built-in Astryx Themes
Astryx provides reference implementations in the packages/themes directory. The y2k theme (packages/themes/y2k/src/y2kTheme.ts) demonstrates a complete token set including color palettes and spacing scales. The gothic theme (packages/themes/gothic/src/gothicTheme.ts) shows dark-mode-oriented token configurations, while the chocolate theme (packages/themes/chocolate/src/chocolateTheme.ts) illustrates custom color theming.
For type safety, consult packages/core/src/theme/types.ts, which contains the TypeScript interfaces for theme objects used throughout the framework. Utility functions in packages/core/src/utils/themeProps.ts assist with converting theme tokens into StyleX-compatible props.
Runtime Theme Switching
To support multiple themes, create separate token sets and conditionally render the appropriate ThemeProvider. Each theme package should export its own provider, allowing you to swap themes by changing the imported provider or dynamically selecting between them based on application state.
Summary
- Define tokens using
stylex.createThemein a.stylex.tsfile to establish CSS custom properties for your design system. - Export a provider component that wraps
@stylexjs/stylex'sThemeProviderand passes your token object to the React context. - Apply the provider at your application's root to inject the theme throughout the component tree.
- Reference built-in themes like
y2k,gothic, andchocolateinpackages/themes/for implementation patterns. - Access theme values via the
useThemehook from@astryxdesign/coreor directly throughstylex.propsin styled components.
Frequently Asked Questions
How do I access theme values inside a React component?
Use the useTheme hook exported from @astryxdesign/core. Import the hook and call it within your component to retrieve the current theme token values, as implemented in packages/core/src/theme/useTheme.ts. This returns an object containing all defined CSS custom properties for the active theme.
Can I extend an existing Astryx theme instead of creating one from scratch?
Yes. Import the base theme tokens from an existing package (such as @astryxdesign/y2k) and merge them with your custom overrides using stylex.createTheme. This approach leverages the core utilities in packages/core/src/utils/themeProps.ts to combine token sets while preserving type safety defined in packages/core/src/theme/types.ts.
Where should I place my custom theme package in the monorepo?
Create your theme under packages/themes/<theme-name>/ to maintain consistency with Astryx's architecture. This location ensures compatibility with the monorepo's workspace configuration and allows other packages to import your theme using the @astryxdesign/<theme-name> namespace convention.
Do I need to define CSS custom properties manually?
While StyleX handles the compile-time generation of CSS, you must map your tokens to CSS custom property strings (e.g., 'var(--my-color-primary)') in your .stylex.ts files. You can optionally define the actual CSS variable values in a separate CSS file or rely on the default values provided in your token definitions, following the pattern seen in packages/themes/y2k/theme.css.d.ts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →