# Astryx: Meta's Open-Source Agent-Ready Design System


Meta released [Astryx](https://astryx.atmeta.com) on June 28, 2026, as a public beta under the MIT license. The system spent eight years inside Meta's monorepo, where it grew to power over 13,000 internal applications including Facebook, Instagram, and Threads. Now it's available to everyone as a **set of npm packages built on React and StyleX, with over 150 accessible components, ten built-in themes, dark mode, production-ready templates, and a CLI designed as much for AI coding agents as for human developers**.

This article covers what makes Astryx different from other design systems, how its theming engine works, and how to use it for custom branding at both the broad token level and the granular component level.

<iframe width="100%" height="315" src="https://www.youtube.com/embed/4GaR7k9VMp4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


## The design system dilemma Astryx addresses

![A screenshot of the Astryx landing page, showcasing its sleek, modern design and key features.](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/a191154e-7777-4133-3ec6-d424311fbb00/lg2x =1280x720)

Two approaches dominate the current design system landscape, and both have well-known tradeoffs.

The first is adopting a comprehensive component library like Material UI. You get a complete, consistent set of components immediately, but your application inherits the library's visual identity. Customization means fighting the library's own styles through CSS overrides, which tends to accumulate technical debt quickly.

The second is the copy-paste approach popularized by Shadcn/UI. You own the component code completely and can modify anything, but every project effectively forks the library. Upstream bug fixes, accessibility improvements, and new features don't flow back automatically. Maintenance falls on your team.

Astryx separates these concerns. Components come from a versioned central package (`@astryxdesign/core`), so upstream improvements reach you through a dependency update rather than a manual copy. Visual identity is controlled through a separate theming layer of design tokens: colors, typography, spacing, radii, and motion. You change the brand without touching component internals.

## Component library and templates


The library ships with 150+ accessible React components. The official docs at [astryx.atmeta.com](https://astryx.atmeta.com) include production-ready templates that demonstrate the components at scale: an issues tracker similar to Jira with grouped rows and dropdown menus, a complete e-commerce checkout form with validation states, a Kanban sprint board with drag-and-drop cards, a VS Code-like IDE interface with file tree and tabbed editor, and an AI chat interface with a Markdown renderer for formatted model output.

These templates aren't toy examples. They're representative of the kind of complex application the system was built to handle inside Meta.

## Theming with `defineTheme`

The theming engine is where Astryx's design shows most clearly. Everything flows from a single `defineTheme` call imported from `@astryxdesign/core/theme`.

```javascript
[label src/themes/customTheme.ts]
import { defineTheme } from '@astryxdesign/core/theme';

export const customTheme = defineTheme({
  name: 'my-theme',
  // theme definitions go here
});
```

The function is fully type-safe. Your editor will autocomplete available options and flag invalid values.

### Generating a full palette from a single accent color

Provide one accent color and Astryx derives a complete accessible palette from it, including light and dark mode variants for backgrounds, surfaces, borders, and text.

```javascript
[label src/themes/customTheme.ts]
export const customTheme = defineTheme({
  name: 'my-theme',
  color: { accent: '#04FF00' },
});
```

![The application UI dynamically updates to a new green-based theme after the accent color is saved in the code.](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/231374f8-0ca3-407a-39bb-2d7fc39ef100/lg2x =1280x720)

One value gives you a complete, coherent color system without manually picking shades.

### Typography scale

The `typography` object sets the font family and establishes a modular scale where all sizes relate mathematically to each other.

```javascript
[label src/themes/customTheme.ts]
export const customTheme = defineTheme({
  name: 'my-theme',
  color: { accent: '#04FF00' },
  typography: {
    scale: { base: 14, ratio: 1.2 },
    body: { family: 'Inter', fallbacks: '-apple-system, sans-serif' },
  },
});
```

`base` sets the paragraph font size in pixels. `ratio` is the multiplier applied at each step up the type hierarchy, so heading sizes stay proportional to body text across any screen size.

### Radius and motion

```javascript
[label src/themes/customTheme.ts]
export const customTheme = defineTheme({
  name: 'my-theme',
  color: { accent: '#04FF00' },
  typography: {
    scale: { base: 14, ratio: 1.2 },
    body: { family: 'Inter', fallbacks: '-apple-system, sans-serif' },
  },
  radius: { base: 8, multiplier: 1 },
  motion: { fast: 175, medium: 410, ratio: 0.75 },
});
```

`radius` sets the base border-radius with a multiplier to generate different sizes per component. `motion` controls transition durations in milliseconds for hover states, focus rings, and other animations.

## Granular overrides

The helper options above handle the majority of cases, but Astryx also provides precise control when you need it.

### Overriding specific tokens

The `tokens` object lets you directly set individual CSS variables. Each token takes an array of two values: light mode and dark mode.

```javascript
[label src/themes/customTheme.ts]
export const customTheme = defineTheme({
  name: 'my-theme',
  // ...
  tokens: {
    '--color-neutral': ['#90e38f', '#90e38f'],
  },
});
```

Because `defineTheme` is type-safe, your editor shows every available token as an autocomplete option. This change applies globally to every component that uses `--color-neutral`.

### Overriding a single component variant

For changes scoped to one component without touching anything else, the `components` object gives you targeted access.

![Code showing the `components` object being used to target the secondary variant of the button and change its color to black.](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/8ff958bb-9cc7-4590-a497-7191cb074100/orig =1280x720)

```javascript
[label src/themes/customTheme.ts]
export const customTheme = defineTheme({
  name: 'my-theme',
  // ...
  components: {
    button: {
      variant: {
        secondary: {
          color: 'black',
        },
      },
    },
  },
});
```

This changes the text color of secondary buttons only. Primary buttons and all other text are unaffected.

### Creating custom variants

You can define entirely new variants beyond the built-in set. The new variant name becomes a valid value for the `variant` prop in TypeScript autocomplete.

```javascript
[label src/themes/customTheme.ts]
components: {
  button: {
    variant: {
      secondary: { color: 'black' },
      myButton: {
        color: 'black',
        backgroundColor: 'red',
      },
    },
  },
},
```

```jsx
[label src/app/page.tsx]
<Button label="Subscribe" variant="myButton" />
```

## Styling flexibility

Astryx is built on StyleX but doesn't require you to use it. Components ship with pre-built CSS, so there's no PostCSS or Babel configuration required.

For one-off style overrides, the `xstyle` prop accepts StyleX style objects:

```jsx
[label src/app/page.tsx]
import * as stylex from '@stylexjs/stylex';
import { Button } from '@astryxdesign/core/Button';

const overrides = stylex.create({
  primaryButton: {
    backgroundColor: 'red',
    color: 'white',
  },
});

function MyComponent() {
  return (
    <Button
      xstyle={overrides.primaryButton}
      label="Primary"
      variant="primary"
    />
  );
}
```

For teams using Tailwind, Astryx provides a bridge that maps your Astryx theme tokens to Tailwind's configuration. Utility classes like `text-primary` and `bg-surface` pull their values from your active Astryx theme, so you keep the Tailwind developer experience while the brand values stay centralized in the theme file.

## The agent-ready layer

One of the more forward-looking aspects of Astryx is how it handles AI coding agents.

![A list of CLI commands to initialize Astryx for different AI agents like Claude, Cursor, and Copilot.](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/f3ff3491-f236-4e7d-9f05-dc347c2d2d00/orig =1280x720)


Astryx ships with an MCP (Model Context Protocol) server that gives AI agents a structured API to discover components, query templates, and check available tokens without scraping documentation. The CLI uses a `--dense` flag that strips human-readable filler from component docs and produces token-efficient payloads optimized for LLM context windows. An agent can run `npx astryx docs styling --dense` to get a machine-readable summary of all styling options without consuming unnecessary context.

This treats AI coding assistants as first-class consumers of the design system rather than an afterthought. The assumption baked into the architecture is that a meaningful percentage of the code written against Astryx in 2026 will be written by a model, and the tooling is built accordingly.

## Getting started

Astryx requires React 19 or newer. The core package is `@astryxdesign/core`. The GitHub repository is at [github.com/facebook/astryx](https://github.com/facebook/astryx) and the documentation is at [astryx.atmeta.com](https://astryx.atmeta.com).

**The system ships ten built-in themes (default, neutral, daily, butter, chocolate, matcha, stone, gothic, brutalist, and y2k)**, so there's a starting point for a range of aesthetics before any custom theming work.

Astryx is currently in public beta. The foundation is mature after eight years of internal use, but the public API is still evolving. It's well-suited for new projects where you control the full stack; teams migrating from established systems should weigh the beta status against stability requirements.