How to Integrate Tailwind CSS with Astryx and StyleX: Complete Setup Guide
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. This file uses Tailwind v4's @theme inline directive to expose Astryx CSS custom-properties as Tailwind variables.
The styling cascade
reset → astryx-base → astryx-theme → tailwind-theme (bridge) → utilities
reset.cssandastryx.cssprovide core component styles@astryxdesign/theme-neutral/theme.css(or any custom theme) supplies token valuestailwind-theme.csstranslates 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.whenconditional 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
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 with this exact layer stack:
@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 under the "Next.js + Tailwind" section.
3. Set up the Theme provider
'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
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
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.
Combining Tailwind and StyleX in the Same Component
For advanced use cases, apply both systems. StyleX handles complex animations; Tailwind handles token-driven layout.
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:
<!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 |
Bridge implementation using @theme inline |
View source |
packages/core/README.md |
Next.js + Tailwind setup guide | View docs |
packages/cli/foundation/agent-docs/agent-docs.mjs |
Styling system detection and precedence logic | View source |
packages/cli/assets/docs/styling-libraries.doc.mjs |
Tailwind bridge documentation and token mappings | View source |
Summary
- Install Tailwind v4+ alongside Astryx core and a theme package
- Import
tailwind-theme.cssafter 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 for Astryx tokens?
No. The 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.
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 →