How to Create a Custom Theme Using the Astryx Theme Build CLI Command
The astryx theme build command compiles a TypeScript theme definition into production-ready CSS and JavaScript bundles by processing token maps and generating static assets.
The Astryx design system provides a dedicated CLI for transforming theme source code into distributable assets. This workflow enables you to define design tokens in TypeScript and export compiled CSS custom properties alongside type-safe JavaScript modules. According to the facebook/astryx source code, the theme compiler located in packages/cli/api/theme/build/ handles token resolution, light-dark mode tuple expansion, and declaration file generation.
Setting Up the Theme Package
Start by scaffolding a new theme directory within the monorepo structure.
Create a folder under packages/themes/ with your theme name (e.g., ocean). Inside this directory, initialize the source structure:
packages/themes/ocean/
└── src/
└── oceanTheme.ts
If your theme ships custom icons, add an icons.tsx file alongside your entry file and import it into the theme definition.
Authoring the Theme Definition
The theme entry file must export a theme object created with the defineTheme utility from @astryxdesign/core/theme.
Required Structure
The theme object requires two properties:
- name: A string identifier for the theme
- tokens: A map where keys are CSS custom property names (always prefixed with
--) and values are either static strings or light-dark tuples (arrays with[lightValue, darkValue])
// packages/themes/ocean/src/oceanTheme.ts
import { defineTheme } from '@astryxdesign/core/theme';
export const oceanTheme = defineTheme({
name: 'ocean',
tokens: {
'--color-accent': ['#0077B6', '#48CAE4'],
'--color-background-surface': ['#F0F8FF', '#0A1628'],
'--color-text-primary': ['#0A1317', '#FFFFFF'],
'--radius-container': '16px',
},
});
Building the Theme
Once your TypeScript source is ready, invoke the build command to generate static assets.
The Build Command Syntax
Execute from the repository root:
npx astryx theme build packages/themes/ocean/src/oceanTheme.ts --out dist/ocean
The CLI performs the following operations:
- Loads the source file and extracts the
defineThemeexport - Resolves all token values (expanding light-dark tuples into CSS custom properties)
- Generates a static CSS file containing the design tokens
- Creates a JavaScript module exporting the built theme object
- Produces accompanying TypeScript declaration files (
.d.ts)
CLI Flags and Options
The command supports additional flags for development workflows:
--watch: Automatically rebuilds when the source file changes, enabling iterative development--json: Prints a machine-readable receipt to stdout describing the build output, including file counts, token overrides, and output sizes
Example with flags:
npx astryx theme build packages/themes/ocean/src/oceanTheme.ts \
--out dist/ocean \
--watch \
--json
Output Files Generated
After successful execution, the output directory contains three essential files:
dist/ocean/
├── theme.css // Compiled CSS with custom properties
├── theme.js // Built Theme object as ES module
└── theme.d.ts // TypeScript declarations for type safety
Consuming the Built Theme
Integrate the compiled assets into your application by importing both the CSS and the theme object.
Importing Assets
Load the generated CSS at your application entry point to inject the custom properties into the document:
// main.tsx or App.tsx
import './dist/ocean/theme.css';
import { oceanTheme } from './dist/ocean/theme.js';
Runtime Integration with ThemeProvider
Pass the exported theme object to the ThemeProvider component (or the Theme component) to apply the design system at runtime:
import { ThemeProvider } from '@astryxdesign/core';
import { oceanTheme } from './dist/ocean/theme.js';
import './dist/ocean/theme.css';
function App() {
return (
<ThemeProvider theme={oceanTheme}>
<YourApplication />
</ThemeProvider>
);
}
Technical Implementation Details
The heavy lifting occurs in the theme compiler implementation within packages/cli/api/theme/build/. The CLI command itself acts as a thin wrapper that parses arguments, loads the source file using Node.js module resolution, and calls the compiler API to process the theme definition into optimized bundles.
Summary
- Scaffold your theme under
packages/themes/<name>/src/<slug>Theme.tswith adefineThemeexport from@astryxdesign/core/theme - Define tokens as CSS custom properties (prefixed with
--) supporting light-dark tuples for automatic dark mode support - Build using
npx astryx theme build <source> --out <dir>to generate CSS, JS, and TypeScript declaration files - Develop efficiently with
--watchfor automatic rebuilds and--jsonfor build analytics - Consume by importing the CSS file and passing the theme object to
ThemeProvider
Frequently Asked Questions
Where does the theme compiler logic live in the repository?
The core compilation logic resides in packages/cli/api/theme/build/. This directory contains the implementation that processes the defineTheme export, resolves token values, and generates the static CSS and JavaScript bundles consumed by the astryx theme build command.
Can I include custom icons in my Astryx theme?
Yes. Place an icons.tsx file in the same directory as your theme entry file (src/<slug>Theme.ts). Import and reference these icons within your theme definition. The build process will bundle them alongside your design tokens when you run the CLI command.
What is the purpose of the --json flag in the theme build command?
The --json flag outputs a machine-readable build receipt to stdout. This JSON object contains metadata about the compilation, including the number of files processed, token override counts, and output file sizes, making it suitable for CI/CD pipelines and automated build verification.
How do I enable automatic rebuilding during theme development?
Add the --watch flag to your build command. This monitors the source TypeScript file for changes and automatically triggers recompilation, regenerating the CSS, JavaScript, and declaration files in your output directory without manual intervention.
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 →