How to Configure Astryx Build Plugins for Vite, Babel, and PostCSS

To configure Astryx build plugins for Vite, Babel, and PostCSS, import astryxStylex from @astryxdesign/build/vite, add it to your Vite plugins array, and pair it with generated Babel and PostCSS configs that handle the two-pass StyleX compilation with custom class-name prefixes and CSS layer ordering.

The facebook/astryx repository provides a comprehensive build toolchain that integrates StyleX into modern frontend workflows. To configure Astryx build plugins for Vite, Babel, and PostCSS, you need to set up three interconnected entry points that handle class-name generation, CSS layer ordering, and module resolution. Each plugin serves a specific role in the build pipeline, from the Vite orchestration layer to the Babel transformation and PostCSS emission stages.

Vite Plugin Configuration (astryxStylex)

The Vite plugin serves as the primary integration point, located in packages/build/src/vite.ts. It orchestrates StyleX compilation, CSS layer ordering, module-resolution aliases, and development server middleware.

Option Handling and Legacy API Detection

The astryxStylex function accepts either modern AstryxVitePluginOptions or legacy AstryxVitePluginLegacyOptions. It detects legacy configurations by checking for a stylexOptions property and automatically forwards these to astryxStylexLegacy when needed (lines 111-118 in packages/build/src/vite.ts).

StyleX Options and Babel Wrapper

By default, the plugin constructs a stylexOptions object with development mode enabled, runtime injection disabled, and CommonJS module resolution (lines 21-28). It resolves a companion wrapper script from src/babel.js and injects it as a Vite plugin before the unplugin's StyleX instance, adding the libraryPrefix option that assigns the astryx prefix to library styles (lines 48-66).

Layer Ordering and Config Aliases

A dedicated Vite plugin inserts a <style> tag declaring CSS layers in the correct order: reset, astryx-base, astryx-theme, and product (lines 70-79). The config plugin also adds critical aliases for @astryxdesign/core to resolve imports to source files, ensuring StyleX can access tokens.stylex files (lines 84-96), and excludes @astryxdesign/* packages from optimizeDeps to prevent pre-bundling that would strip StyleX calls (lines 98-100).

Dev Server Middleware

During development, the plugin intercepts requests to /virtual:stylex.css and implements a split-layer middleware (lines 380-492). This extracts compiled rules from StyleX's shared store, separates them into library and product groups based on the libraryPattern, processes each through processStylexRules, and serves them wrapped in their respective @layer declarations.

Babel Plugin Configuration (@astryxdesign/build/babel)

The Babel plugin, exported from packages/build/src/babel.js, wraps @stylexjs/babel-plugin to inject custom class-name prefixes.

Config Helper and Wrapper Script

The babel function in packages/build/src/config.js (lines 59-65) returns a standard Babel configuration that loads the wrapper script. This wrapper adds the classNamePrefix option, defaulting to astryx for library code while keeping the default x prefix for product code. The helper stylexOptions (lines 38-48) builds base options including dev flags, runtime injection disabled, and treeshake compensation.

PostCSS Plugin Configuration (@astryxdesign/build/postcss)

The PostCSS plugin, defined in packages/build/src/index.js, performs the two-pass StyleX compilation and emits CSS into distinct layers.

Two-Pass Compilation and CSS Layer Emission

The plugin collects source files based on include globs (lines 28-38), then runs two Babel transforms: one with the astryx library prefix and one with the default x prefix (lines 98-108). It aggregates StyleX metadata into separate maps for library and product styles (lines 61-84), calls processStylexRules to generate CSS strings, and wraps each in @layer blocks (astryx-base and product) before replacing the @stylex at-rule in the source (lines 14-22, 33-36).

The postcss generator in packages/build/src/config.js (lines 75-88) creates the configuration that loads this plugin along with autoprefixer, and supports an extraInclude option for additional file globs.

Complete Configuration Example

To wire everything together in a Vite project:

// vite.config.ts
import {defineConfig} from 'vite';
import react from '@vitejs/plugin-react';
import {astryxStylex} from '@astryxdesign/build/vite';

export default defineConfig({
  plugins: [...astryxStylex(), react()],
});
// babel.config.js
const {babel} = require('@astryxdesign/build');

module.exports = babel(__dirname);
// postcss.config.js
const {postcss} = require('@astryxdesign/build');

module.exports = postcss(__dirname);

This setup gives you a complete pipeline where Vite handles the build orchestration, Babel transforms the JavaScript with proper class-name prefixes, and PostCSS emits the final CSS into ordered layers.

Customizing Plugin Options

You can customize the configuration through several options:

Layer names – Override the default astryx-base and product layer names via the layers option:

plugins: [
  ...astryxStylex({layers: {library: 'my-lib', product: 'my-app'}}),
  react(),
]

Library prefix – Change the library class-name prefix to avoid clashes:

plugins: [...astryxStylex({stylexPrefix: 'myPrefix'}), react()]

LightningCSS targets – Pass lightningcssTargets for optimization (see LIGHTNINGCSS_TARGETS constants in vite.ts).

PostCSS extra includes – Add additional file globs via the extraInclude option in the PostCSS configuration, useful for monorepo setups.

All options are fully typed in AstryxVitePluginOptions (lines 40-87 in packages/build/src/vite.ts).

Summary

  • The astryxStylex Vite plugin in packages/build/src/vite.ts orchestrates StyleX compilation, CSS layer ordering, and dev-server middleware.
  • The Babel plugin in packages/build/src/babel.js wraps @stylexjs/babel-plugin to inject the astryx class-name prefix for library code while keeping x for product code.
  • The PostCSS plugin in packages/build/src/index.js runs two-pass compilation and emits CSS into astryx-base and product layers.
  • Use optimizeDeps.exclude to prevent Vite from pre-bundling @astryxdesign/* packages, which would strip StyleX calls and cause runtime errors.
  • The dev server serves virtual CSS at /virtual:stylex.css with automatic layer splitting based on the libraryPattern configuration.

Frequently Asked Questions

How do I configure Astryx build plugins for Vite, Babel, and PostCSS in an existing project?

Import astryxStylex from @astryxdesign/build/vite and spread it into your Vite plugins array. Then create babel.config.js and postcss.config.js files that use the babel and postcss helpers from @astryxdesign/build. This establishes the three-way integration that handles StyleX compilation, class-name prefixing, and CSS layer emission without manual CSS file management.

Why does the Vite plugin exclude @astryxdesign/* packages from dependency optimization?

Vite's dependency pre-bundling would strip StyleX calls from the library code, causing runtime errors. The plugin automatically adds optimizeDeps.exclude patterns for all @astryxdesign/* packages (lines 98-100 in packages/build/src/vite.ts) to preserve the StyleX metadata needed for the Babel and PostCSS transformations.

What is the difference between the astryx and x class-name prefixes?

The astryx prefix is applied to library code (design system components) while the x prefix is used for product code (application-specific styles). This separation allows the PostCSS plugin in packages/build/src/index.js to split styles into distinct CSS layers (astryx-base vs product) and prevents class-name collisions between library and application code during the two-pass compilation.

How does the dev server handle CSS layer splitting?

When the dev server receives a request for /virtual:stylex.css, the middleware in packages/build/src/vite.ts (lines 380-492) extracts rules from StyleX's shared store, splits them by origin using the libraryPattern, processes each group through processStylexRules, and wraps them in the appropriate @layer declarations before serving the response. This ensures library styles are contained in astryx-base layers while product styles remain in product layers during development.

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 →