How to Configure StyleX Build Plugins for Next.js and Vite with Astryx

Astryx provides native StyleX integrations via the @stylexswc/nextjs-plugin for Next.js SWC pipelines and @stylexjs/unplugin for Vite, enabling compile-time CSS extraction without altering core compiler behavior.

Astryx is a Meta-backed design system that ships first-class StyleX support through dedicated build plugins. This guide demonstrates how to configure these plugins for Next.js and Vite based on the actual implementation in the facebook/astryx repository.

Next.js SWC Integration

Astryx integrates with Next.js through the SWC-based StyleX transform. This approach preserves the native Next.js compiler and next/font handling while adding compile-time CSS generation.

Install the Plugin

Add the community SWC plugin to your Next.js workspace:

pnpm add -D @stylexswc/nextjs-plugin

Configure next.config.js

Wire the plugin into your Next.js configuration via the experimental.swcPlugins array. As shown in apps/example-nextjs-stylex/next.config.js, this keeps the Next.js compiler intact while injecting StyleX processing:

const { default: stylexPlugin } = require('@stylexswc/nextjs-plugin');

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    swcPlugins: [
      [stylexPlugin, { dev: true }],
    ],
  },
};

module.exports = nextConfig;

Runtime Extraction

The SWC plugin performs compile-time CSS extraction and generates a static stylesheet. According to the implementation in packages/build/src/vite.ts, it injects a runtime-injection shim only when the dev option is set to true.

Vite Unplugin Integration

For Vite projects, Astryx uses @stylexjs/unplugin to process StyleX calls within Vite's native pipeline.

Install the Unplugin

Add the StyleX unplugin to your development dependencies:

pnpm add -D @stylexjs/unplugin

Configure vite.config.ts

Import the plugin from @stylexjs/unplugin/vite and add it to your plugins array. The example in apps/example-vite/vite.config.ts demonstrates this setup:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { stylexPlugin } from '@stylexjs/unplugin/vite';

export default defineConfig({
  plugins: [
    react(),
    stylexPlugin({
      dev: true,
      output: 'dist/stylex',
    }),
  ],
});

Lazy Loading and HMR

As implemented in packages/build/src/vite.ts, the plugin lazy-loads the StyleX integration, extracts its shared store via __stylexGetSharedStore, and wires up hot-module-replacement for development builds.

Writing Component Styles

Once configured, consume StyleX in your components using tokens from @astryxdesign/core. This component code works identically in both Next.js and Vite environments:

import * as stylex from '@stylexjs/stylex';
import { tokens } from '@astryxdesign/core/theme/tokens.stylex';

const styles = stylex.create({
  button: {
    backgroundColor: tokens.brandPrimary,
    padding: `calc(${tokens.spaceMedium} * 2)`,
    ':hover': { opacity: 0.85 },
  },
});

export function FancyButton({ children }) {
  return <button {...stylex.props(styles.button)}>{children}</button>;
}

Configuration Options Comparison

Both plugins support consistent options for controlling development behavior and output:

  • Runtime Injection: Enable via dev: true to inject a development shim; disabled in production builds
  • CSS Output: Next.js manages output internally (typically .next/static/css), while Vite accepts an output parameter (e.g., dist/stylex)
  • Compatibility: Next.js plugin works with Next.js 13+ (App Router), while the Vite unplugin supports Vite 8 as used across Astryx

Summary

  • Use @stylexswc/nextjs-plugin in Next.js via experimental.swcPlugins to preserve SWC compilation
  • Use @stylexjs/unplugin/vite in Vite projects for rollup-based CSS extraction
  • Both plugins dedupe atomic CSS at compile time and support optional runtime injection in development
  • Reference packages/cli/docs/styling.doc.mjs for authoritative configuration documentation
  • Token definitions in packages/core/theme/tokens.stylex.ts provide the design system values consumed by both frameworks

Frequently Asked Questions

Does the StyleX plugin break Next.js font optimization?

No. The SWC-based integration preserves next/font handling because it operates as a transform within the existing SWC pipeline rather than replacing the compiler. The plugin only processes StyleX-specific calls, leaving other transformations untouched.

Where does the generated CSS get written in Vite builds?

The Vite plugin emits CSS to the location specified by the output option (defaulting to dist/stylex). This generated file is served alongside your bundle, and the plugin handles deduplication of atomic classes across your component tree.

Can I use Astryx design tokens in both Next.js and Vite projects?

Yes. Import tokens from @astryxdesign/core/theme/tokens.stylex as shown in packages/core/theme/tokens.stylex.ts. These tokens are framework-agnostic StyleX definitions that work identically whether compiled through the Next.js SWC plugin or the Vite unplugin.

What happens if I disable the dev option in production?

When dev is set to false or omitted, the plugins skip runtime injection and perform only static CSS extraction. This results in zero runtime overhead, with all styles embedded in the generated CSS files rather than being injected by JavaScript.

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 →