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.createTheme in a .stylex.ts file to establish CSS custom properties for your design system.
  • Export a provider component that wraps @stylexjs/stylex's ThemeProvider and 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, and chocolate in packages/themes/ for implementation patterns.
  • Access theme values via the useTheme hook from @astryxdesign/core or directly through stylex.props in 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →