# How to Integrate Tailwind CSS with Astryx and StyleX: Complete Setup Guide

> Integrate Tailwind CSS with Astryx and StyleX using the native Tailwind bridge. Map design tokens to utility classes for concise and efficient styling. Get the complete setup guide.

- Repository: [Meta/astryx](https://github.com/facebook/astryx)
- Tags: how-to-guide
- Published: 2026-08-05

---

**Astryx provides a native Tailwind bridge via `@astryxdesign/core/tailwind-theme.css` that maps design tokens directly to Tailwind utility classes, enabling you to use concise utilities like `bg-surface` and `text-primary` instead of verbose CSS custom properties.**

Integrating Tailwind CSS with **Astryx** (Facebook's design system) and **StyleX** lets you combine utility-first productivity with a token-driven design system. This guide walks through the exact source files, import order, and configuration patterns used in the `facebook/astryx` repository.

## How the Tailwind Bridge Works

Astryx ships a dedicated **Tailwind bridge** at [`packages/core/src/tailwind-theme.css`](https://github.com/facebook/astryx/blob/main/packages/core/src/tailwind-theme.css). This file uses Tailwind v4's `@theme inline` directive to expose Astryx CSS custom-properties as Tailwind variables.

### The styling cascade

```text
reset → astryx-base → astryx-theme → tailwind-theme (bridge) → utilities

```

- [`reset.css`](https://github.com/facebook/astryx/blob/main/reset.css) and [`astryx.css`](https://github.com/facebook/astryx/blob/main/astryx.css) provide core component styles
- `@astryxdesign/theme-neutral/theme.css` (or any custom theme) supplies token values
- [`tailwind-theme.css`](https://github.com/facebook/astryx/blob/main/tailwind-theme.css) translates tokens into Tailwind-readable variables
- Tailwind utilities (`bg-*`, `text-*`, `rounded-*`) consume those variables

This architecture requires **no PostCSS plugins or Babel transforms**. The bridge sits between layers and leverages Tailwind v4's native `@import` and `@layer` handling.

## Choosing Between StyleX and Tailwind in Astryx

Astryx supports **both** styling systems. Understanding their roles prevents conflicts:

| System | Use case | Implementation |
|--------|----------|----------------|
| **StyleX** (`@stylexjs/stylex`) | Component authoring, runtime calculations, complex animations | Compile-time class generation with deterministic naming (`astryx…`) |
| **Tailwind** | Rapid prototyping, utility-first workflows, layout/spacing | Runtime utility classes reading Astryx tokens |

**Precedence rule**: When both systems are present, Astryx gives priority to StyleX. The `detectStylingSystem` function in `packages/cli/foundation/agent-docs/agent-docs.mjs` implements this hierarchy: `stylex → tailwind → css`.

Use **StyleX** for:
- Fine-grained component control
- `stylex.when` conditional nesting
- Compile-time fallbacks and logical properties

Use **Tailwind** for:
- Quick layout adjustments
- Design-token-driven utilities without manual `var()` syntax

## Step-by-Step Integration for Next.js

### 1. Install dependencies

```bash
npm install @astryxdesign/core @astryxdesign/theme-neutral @stylexjs/stylex
npm install -D tailwindcss@^4.0.0

```

StyleX is a peer dependency; Tailwind v4+ is required for the `@theme inline` support.

### 2. Configure global CSS import order

Create [`src/app/globals.css`](https://github.com/facebook/astryx/blob/main/src/app/globals.css) with this exact layer stack:

```css
@layer reset, theme, base, astryx-base, astryx-theme, components, utilities;

/* Tailwind core layers */
@import 'tailwindcss/theme.css' layer(theme);
@import 'tailwindcss/preflight.css' layer(base);

/* Astryx core styles */
@import '@astryxdesign/core/reset.css';
@import '@astryxdesign/core/astryx.css';
@import '@astryxdesign/theme-neutral/theme.css';

/* Tailwind-Astryx bridge — maps tokens to utilities */
@import '@astryxdesign/core/tailwind-theme.css';

/* Tailwind utilities */
@import 'tailwindcss/utilities.css' layer(utilities);

```

**Critical**: The bridge must import **after** the theme but **before** utilities. This ordering is documented in [`packages/core/README.md`](https://github.com/facebook/astryx/blob/main/packages/core/README.md) under the "Next.js + Tailwind" section.

### 3. Set up the Theme provider

[`src/app/providers.tsx`](https://github.com/facebook/astryx/blob/main/src/app/providers.tsx):

```tsx
'use client';

import Link from 'next/link';
import {Theme} from '@astryxdesign/core/theme';
import {LinkProvider} from '@astryxdesign/core/Link';
import {neutralTheme} from '@astryxdesign/theme-neutral/built';

export function Providers({children}: {children: React.ReactNode}) {
  return (
    <Theme theme={neutralTheme}>
      <LinkProvider component={Link}>{children}</LinkProvider>
    </Theme>
  );
}

```

### 4. Apply to layout

[`src/app/layout.tsx`](https://github.com/facebook/astryx/blob/main/src/app/layout.tsx):

```tsx
import './globals.css';
import {Providers} from './providers';

export default function RootLayout({children}: {children: React.ReactNode}) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

```

### 5. Use Tailwind utilities with Astryx components

```tsx
import {Button, Card} from '@astryxdesign/core';

export default function Page() {
  return (
    <Card className="p-6 shadow-lg rounded-lg bg-surface">
      <h1 className="text-2xl font-bold text-primary mb-4">
        Welcome to Astryx + Tailwind
      </h1>
      <Button label="Primary" variant="primary" className="mt-2" />
    </Card>
  );
}

```

`bg-surface`, `text-primary`, `rounded-lg`, and `shadow-lg` map directly to Astryx tokens via the bridge in [`tailwind-theme.css`](https://github.com/facebook/astryx/blob/main/tailwind-theme.css).

## Combining Tailwind and StyleX in the Same Component

For advanced use cases, apply both systems. StyleX handles complex animations; Tailwind handles token-driven layout.

[`src/components/Badge.tsx`](https://github.com/facebook/astryx/blob/main/src/components/Badge.tsx):

```tsx
import stylex from '@stylexjs/stylex';
import {Badge as AstryxBadge} from '@astryxdesign/core';

const styles = stylex.create({
  root: {
    animationName: stylex.keyframes({
      '0%': {transform: 'rotate(0deg)'},
      '100%': {transform: 'rotate(360deg)'},
    }),
    animationDuration: '2s',
    animationIterationCount: 'infinite',
  },
});

export function Badge({children}: {children: React.ReactNode}) {
  return (
    <AstryxBadge
      {...stylex.props(styles.root)}   // StyleX: animation
      className="bg-success text-on-success rounded-sm px-2 py-1"  // Tailwind: tokens
    >
      {children}
    </AstryxBadge>
  );
}

```

StyleX generates a compile-time class name (`astryx…` prefix). Tailwind utilities layer on top. The precedence rule in `packages/cli/foundation/agent-docs/agent-docs.mjs` ensures StyleX wins any conflicts.

## Zero-Build CDN Setup

For rapid prototyping without a build step, load layers via CDN:

```html
<!doctype html>
<html data-astryx-theme="neutral">
  <head>
    <link rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/tailwindcss@4/dist/headwind.css">
    <link rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/@astryxdesign/core/reset.css">
    <link rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/@astryxdesign/core/astryx.css">
    <link rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/@astryxdesign/theme-neutral/theme.css">
    <link rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/@astryxdesign/core/tailwind-theme.css">
    <link rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/tailwindcss@4/dist/utilities.css">
  </head>
  <body class="bg-surface text-primary">
    <div class="p-4 rounded-lg shadow-md bg-card">
      <h2 class="text-xl font-medium">CDN + Tailwind</h2>
      <button class="mt-2 px-4 py-2 bg-primary text-on-primary rounded-md">
        Click me
      </button>
    </div>
    
    <script src="https://unpkg.com/react@19/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@19/umd/react-dom.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@astryxdesign/core/dist/astryx.umd.js"></script>
    <script>
      const {Button} = window.Astryx;
      const e = React.createElement;
      ReactDOM.createRoot(document.body).render(
        e(Button, {label: "Astryx UI", variant: "primary"})
      );
    </script>
  </body>
</html>

```

The `data-astryx-theme="neutral"` attribute activates the theme. All token utilities work because the bridge loads in the correct sequence.

## Key Source Files and References

| File | Purpose | Location |
|------|---------|----------|
| [`packages/core/src/tailwind-theme.css`](https://github.com/facebook/astryx/blob/main/packages/core/src/tailwind-theme.css) | Bridge implementation using `@theme inline` | [View source](https://github.com/facebook/astryx/blob/main/packages/core/src/tailwind-theme.css) |
| [`packages/core/README.md`](https://github.com/facebook/astryx/blob/main/packages/core/README.md) | Next.js + Tailwind setup guide | [View docs](https://github.com/facebook/astryx/blob/main/packages/core/README.md#nextjs--tailwind) |
| `packages/cli/foundation/agent-docs/agent-docs.mjs` | Styling system detection and precedence logic | [View source](https://github.com/facebook/astryx/blob/main/packages/cli/foundation/agent-docs/agent-docs.mjs) |
| `packages/cli/assets/docs/styling-libraries.doc.mjs` | Tailwind bridge documentation and token mappings | [View source](https://github.com/facebook/astryx/blob/main/packages/cli/assets/docs/styling-libraries.doc.mjs) |

## Summary

- **Install Tailwind v4+** alongside Astryx core and a theme package
- **Import [`tailwind-theme.css`](https://github.com/facebook/astryx/blob/main/tailwind-theme.css) after the theme** but before Tailwind utilities to enable token mapping
- **Use Tailwind utilities** (`bg-surface`, `text-primary`, `rounded-lg`) for rapid, token-driven styling
- **Reserve StyleX** for component-level complexity: animations, runtime logic, and compile-time optimizations
- **Follow the cascade order**: reset → astryx-base → astryx-theme → tailwind-theme → utilities

Both systems share the same Astryx token foundation, so your design system stays consistent regardless of which styling approach you choose for a given task.

## Frequently Asked Questions

### Can I use Tailwind v3 with Astryx?

No. The Tailwind bridge relies on Tailwind v4's `@theme inline` directive for exposing CSS custom-properties as Tailwind variables. Tailwind v3 lacks this native mechanism and would require manual configuration that the bridge does not support.

### What happens if I use both `className` and StyleX on the same element?

Both classes apply. StyleX receives precedence per `detectStylingSystem` in `packages/cli/foundation/agent-docs/agent-docs.mjs`. This means StyleX properties override Tailwind when they conflict, but non-conflicting utilities from both systems combine normally.

### Do I need to configure [`tailwind.config.js`](https://github.com/facebook/astryx/blob/main/tailwind.config.js) for Astryx tokens?

No. The [`tailwind-theme.css`](https://github.com/facebook/astryx/blob/main/tailwind-theme.css) bridge uses `@theme inline` to inject Astryx tokens directly into Tailwind's variable system. No JavaScript configuration or `content` array updates are required—Tailwind v4's CSS-first configuration handles everything.

### Can I use a custom Astryx theme with the Tailwind bridge?

Yes. Replace `@astryxdesign/theme-neutral/theme.css` with your custom theme CSS file. The bridge reads whatever CSS custom-properties are defined, so any valid Astryx theme automatically generates corresponding Tailwind utilities.