StyleX Unplugin Bundler Plugin
@stylexjs/unplugin is a universal bundler plugin built upon the `unplugin` abstraction, designed to compile StyleX CSS at build time. It aggregates CSS from all transformed modules within a project and injects the resulting styles into an existing CSS asset produced by the bundler. If no such asset is found, it emits a stable fallback CSS file. Currently at version 0.17.6, the package is actively maintained and supports various bundlers including Vite, Rollup, Webpack, Rspack, and esbuild. Its key differentiators lie in providing a unified, declarative API across these diverse build environments, ensuring consolidated and deterministic StyleX output. Furthermore, it offers specialized development helpers via virtual modules like `virtual:stylex:runtime` and `/virtual:stylex.css` to facilitate efficient hot CSS reloads during development, simplifying the integration of StyleX into modern JavaScript build pipelines.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'webpack') at ...
cause Attempting to use `require('@stylexjs/unplugin')` directly in a CommonJS context (e.g., Webpack config) without accessing the default export.fixModify your `require` statement to `const stylexPlugin = require('@stylexjs/unplugin').default;`. -
Hot Module Replacement (HMR) for CSS is not working in development mode, or styles are not updating.
cause Incorrect `devMode` configuration, virtual module injection issues, or missing HTML setup for dev assets.fixVerify `devMode: 'full'` is set in your plugin options. Ensure `<link rel="stylesheet" href="/virtual:stylex.css" />` and `import('virtual:stylex:runtime')` are correctly placed in your HTML shell or client entrypoint. Check your browser's developer console for any errors related to loading these virtual modules. -
StyleX styles are not being applied in the production build or are missing from the final CSS bundle.
cause The bundler is not configured to emit a CSS asset, or `@stylexjs/unplugin` is not correctly integrated into the plugin chain or is misconfigured.fixEnsure your bundler produces at least one CSS output file (e.g., configure `MiniCssExtractPlugin` for Webpack, or rely on Vite's default CSS handling). Double-check that `stylexPlugin.<bundler-name>()` is correctly listed and configured within your bundler's plugin array.
Warnings
- gotcha When configuring the plugin in CommonJS environments (e.g., Webpack or Rspack), the default export from `@stylexjs/unplugin` must be explicitly accessed using `.default`.
- gotcha The `devMode` option (e.g., `'full'`, `'css-only'`, `'off'`) in the plugin configuration significantly impacts the development experience and Hot Module Replacement (HMR) behavior. Misconfiguration can lead to unresponsive or incomplete hot reloads.
- gotcha Virtual modules like `virtual:stylex:runtime` and `/virtual:stylex.css` might encounter CORS issues or require specific handling in frameworks that proxy assets differently, potentially preventing proper loading during development.
- gotcha In Vite, packages depending on `@stylexjs/stylex` are typically auto-discovered and de-optimized. However, if your setup includes additional StyleX-consuming libraries not automatically detected, their StyleX code may not be transformed correctly.
- gotcha The plugin is designed to append StyleX CSS to an existing CSS asset produced by your bundler. If your build setup does not generate any CSS asset, the plugin will emit a fallback `stylex.css` in the output directory.
- gotcha When using the esbuild adapter via `stylex.esbuild()`, the `metafile: true` option is a mandatory configuration for esbuild to allow the plugin to correctly locate and process CSS outputs.
Install
-
npm install stylex-unplugin -
yarn add stylex-unplugin -
pnpm add stylex-unplugin
Imports
- stylex
import stylex from '@stylexjs/unplugin';
- stylex (Webpack/Rspack CommonJS)
const stylex = require('@stylexjs/unplugin');const stylex = require('@stylexjs/unplugin').default; - virtual:stylex:runtime
import 'virtual:stylex:runtime';
- virtual:stylex.css
import 'virtual:stylex.css';
<link rel="stylesheet" href="/virtual:stylex.css" />
Quickstart
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import stylexPlugin from '@stylexjs/unplugin';
export default defineConfig({
plugins: [
stylexPlugin.vite({
// Optional: Manually include packages that use StyleX and should be transformed.
// externalPackages: ['lib-using-stylex'],
// devMode: 'full' // Controls HMR behavior: 'full' | 'css-only' | 'off'
}),
react(),
],
});
// To enable HMR in development, add the following to your root HTML file (e.g., public/index.html):
/*
<link rel="stylesheet" href="/virtual:stylex.css" />
<script type="module">
import 'virtual:stylex:runtime'; // or 'virtual:stylex:css-only' if only CSS HMR is needed
</script>
*/