npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@stylexswc/webpack-plugin

v0.20.0

Published

StyleX plugin for webpack powered by a Rust NAPI-RS/SWC compiler. Fast StyleX transforms and CSS extraction without Babel.

Readme

@stylexswc/webpack-plugin

StyleX plugin for webpack, powered by a Rust compiler (NAPI-RS + SWC). Part of the StyleX SWC Plugin workspace.

This plugin compiles StyleX code in your webpack build with @stylexswc/rs-compiler, a Rust implementation of the StyleX transform, instead of the official Babel plugin. Your StyleX code stays exactly the same — only the build step changes, with per-file transforms 5x to 10x faster than Babel (performance). The plugin transforms your source files, collects the generated rules, and extracts them into a dedicated CSS chunk.

This is a community project and is not affiliated with Meta. It tracks the official StyleX releases

and requires Node.js 20 or newer. For Next.js projects, use @stylexswc/nextjs-plugin instead — it wires this plugin into the Next.js build for you.

Installation

npm install --save-dev @stylexswc/webpack-plugin

The Rust compiler (@stylexswc/rs-compiler) is installed automatically as a dependency. Your application still needs the StyleX runtime:

npm install @stylexjs/stylex

Usage

Add the plugin to your webpack config:

const StylexPlugin = require('@stylexswc/webpack-plugin');
const path = require('path');

const config = (env, argv) => ({
  entry: {
    main: './js/index.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
  },
  plugins: [
    new StylexPlugin({
      rsOptions: {
        dev: argv.mode === 'development',
      },
    }),
  ],
  cache: true,
});

module.exports = config;

Then import the carrier stylesheet once at the entry point of your app (e.g. index.js, App.tsx):

import '@stylexswc/webpack-plugin/stylex.css';

The plugin appends the extracted StyleX CSS to this asset during the build. Like a regular CSS file, it must flow through your CSS pipeline, so a css-loader + MiniCssExtractPlugin.loader rule (or webpack's built-in CSS support) has to cover .css files.

The carrier import is a recommendation, not a hard requirement. The plugin also appends tiny per-module CSS imports to every StyleX module, so any part of the bundle that renders a StyleX component pulls the stylesheet in on its own — most builds emit correct CSS even without the carrier. What the carrier adds is a guarantee that doesn't depend on your module graph: the stylesheet is always present and loaded with the entrypoint. That matters when something consumes StyleX output without rendering a StyleX component — plain CSS reading defineVars custom properties (var(--x…)), or injected markup carrying StyleX class names. If styles would actually be lost (no CSS asset exists to receive them at all), the plugin raises a compilation warning; it stays silent as long as the output is correct, carrier or not.

[!IMPORTANT] Migrating from 0.17.x: version 0.18.0 reworks the CSS extraction architecture. The CSS is no longer injected through auto-generated stylex.virtual.css imports — add the import '@stylexswc/webpack-plugin/stylex.css'; carrier import to your app entrypoint (recommended; see above for when you can skip it). Paths embedded in module identifiers are now relative to compiler.context, which changes chunk hashes once and makes builds reproducible across machines.

Plugin Options

Basic Options

rsOptions

  • Type: Partial<StyleXOptions>
  • Optional
  • Description: StyleX compiler options passed to @stylexswc/rs-compiler. For the standard options, see the official StyleX documentation.

[!NOTE] The include and exclude options are exclusive to the Rust compiler and are not available in the official StyleX Babel plugin.

rsOptions.include
  • Type: (string | RegExp)[]
  • Optional
  • Description: Glob patterns or regular expressions selecting the files to transform. When specified, only files matching at least one pattern are transformed. Patterns are matched against paths relative to the current working directory.
rsOptions.exclude
  • Type: (string | RegExp)[]
  • Optional
  • Description: Glob patterns or regular expressions excluding files from the transform. A file matching any exclude pattern is skipped even if it matches an include pattern. Patterns are matched against paths relative to the current working directory.

stylexImports

  • Type: Array<string | { as: string, from: string }>
  • Default: ['stylex', '@stylexjs/stylex']
  • Description: Specifies where StyleX is imported from. Supports both string paths and import aliases.

useCSSLayers

  • Type: boolean
  • Default: false
  • Description: Wraps the generated CSS in cascade layers for better style isolation.

nextjsMode

  • Type: boolean
  • Default: false
  • Description: Enables Next.js-specific optimizations and compatibility features. Leave off unless the plugin is driven by the Next.js integration.

extractCSS

  • Type: boolean
  • Optional
  • Default: true
  • Description: Controls whether the generated CSS is extracted into a separate file.

loaderOrder

  • Type: 'first' | 'last'

  • Optional

  • Default: 'first'

  • Description: When the StyleX transformation runs relative to other webpack loaders.

    • 'first' (recommended): StyleX processes the source code before any other loaders run. Automatically enables injectStylexSideEffects so tree-shaking cannot remove .stylex and .consts imports.
    • 'last': StyleX processes after all other loaders have completed. Use this if other loaders (TypeScript, SWC plugins) must transform your code before StyleX sees it.

    Why 'first' is recommended: after StyleX rewrites your code, imports from .stylex and .consts files can look unused to subsequent loaders and bundler passes and get tree-shaken away:

    // Before transformation
    import { colors } from './theme.stylex';
    const styles = stylex.create({
      root: { backgroundColor: colors.primary },
    });
    
    // After StyleX transformation (appears unused to the bundler)
    import { colors } from './theme.stylex'; // may be tree-shaken!
    const styles = { root: { backgroundColor: 'x1a2b3c', $$css: true } };

    With loaderOrder: 'first', the plugin preserves these imports by injecting side-effect imports automatically.

stylexPackages

  • Type: string[]
  • Optional
  • Default: ['@stylexjs/']
  • Description: node_modules is excluded from the transform by default, even for files that reference a StyleX import. Packages that ship untransformed StyleX source (component libraries, token packages) must be allowlisted here with path fragments:
new StylexPlugin({
  stylexPackages: ['@stylexjs/', 'my-design-system'],
});

carrierCss

Path to a custom carrier stylesheet that receives the extracted StyleX CSS — the file you import once at your app entrypoint. Absolute, or relative to compiler.context. Replaces the default @stylexswc/webpack-plugin/stylex.css carrier: useful when another file named stylex.css in your project would collide with the default filename pattern, or when you want the carrier to live in your own source tree.

new StylexPlugin({
  carrierCss: './src/styles/stylex-carrier.css',
});
// src/index.js
import './styles/stylex-carrier.css';

If styles get extracted but no CSS asset is emitted to receive them (e.g. a custom cacheGroup renamed the chunk), the plugin raises a compilation warning instead of silently dropping the CSS.

Advanced Options

transformCss

  • Type: (css: string, filePath: string | undefined) => string | Buffer | Promise<string | Buffer>
  • Optional
  • Description: Custom CSS post-processing. The plugin injects CSS after all loaders have run, so postcss-loader never sees it — apply PostCSS, autoprefixer, or a minifier here instead:
new StylexPlugin({
  transformCss: async (css, filePath) => {
    const postcss = require('postcss');
    const result = await postcss([require('autoprefixer')]).process(css, {
      from: filePath,
    });
    return result.css;
  },
});

cacheGroup

  • Type: CacheGroupOptions (webpack cache group configuration)
  • Optional
  • Description: Replaces the default webpack cache group used for StyleX CSS extraction. By default the plugin creates a dedicated cache group named _stylex-webpack-generated. A custom cache group replaces the defaults with standard splitChunks semantics — e.g. omitting test matches every module, which funnels all extracted CSS into the StyleX chunk. name must be a static string and falls back to the default chunk name. String and RegExp shorthand values are treated as test. false disables the plugin's cache group entirely — extracted styles then have no CSS asset to land in and the build warns; to turn off extraction, use extractCSS: false instead. Include type: 'css/mini-extract', chunks and enforce yourself when you need them.

Default cache group configuration:

{
  name: '_stylex-webpack-generated',
  test: /<packaged carrier path>|stylex-virtual\.css/,
  type: 'css/mini-extract',
  chunks: 'all',
  enforce: true,
}

Custom cache group:

new StylexPlugin({
  cacheGroup: {
    name: 'my-stylex-bundle',
    chunks: 'initial',
    priority: 20,
    enforce: true,
  },
});

Example Configuration

const StylexPlugin = require('@stylexswc/webpack-plugin');

module.exports = {
  plugins: [
    new StylexPlugin({
      rsOptions: {
        dev: process.env.NODE_ENV !== 'production',
        include: ['src/**/*.{ts,tsx}', 'components/**/*.{ts,tsx}'],
        exclude: ['**/*.test.*', '**/*.stories.*', '**/__tests__/**'],
      },
      stylexImports: ['@stylexjs/stylex', { from: './theme', as: 'tokens' }],
      useCSSLayers: true,
      loaderOrder: 'first',
      transformCss: async css => {
        const postcss = require('postcss');
        const result = await postcss([require('autoprefixer')]).process(css);
        return result.css;
      },
    }),
  ],
};

Path Filtering Examples

Include only specific directories:

new StylexPlugin({
  rsOptions: {
    include: ['src/**/*.tsx', 'app/**/*.tsx'],
  },
});

Exclude test and build files:

new StylexPlugin({
  rsOptions: {
    exclude: ['**/*.test.*', '**/*.spec.*', '**/dist/**'],
  },
});

Using regular expressions:

new StylexPlugin({
  rsOptions: {
    include: [/src\/.*\.tsx$/],
    exclude: [/\.test\./, /\.stories\./],
  },
});

Transform only specific packages from node_modules — note that node_modules is excluded regardless of rsOptions.include/exclude, so allowlist packages with stylexPackages instead:

new StylexPlugin({
  rsOptions: {
    include: ['src/**/*.{ts,tsx}'],
    exclude: ['**/*.test.*'],
  },
  stylexPackages: ['@stylexjs/open-props', '@my-org/design-system'],
});

FAQ

Do I still need @stylexjs/babel-plugin?

No. This plugin replaces the Babel plugin in your build. You only keep @stylexjs/stylex as your app's runtime dependency, and your stylex.create / stylex.props code does not change.

My styles from a component library are missing. Why?

node_modules is excluded by default. Add the package to stylexPackages (for example stylexPackages: ['@stylexjs/', 'my-design-system']) so the StyleX loader processes it.

Imports from my .stylex.ts token files disappear after the build

That is tree-shaking removing imports that look unused after the transform. Keep the default loaderOrder: 'first', which injects side-effect imports to protect them.

Can I run PostCSS on the generated CSS?

Yes — through the transformCss option. The StyleX CSS is produced after the regular loader pipeline, so postcss-loader alone will not see it.

Is this an official StyleX package?

No. It is a community-maintained alternative to the official tooling and is not affiliated with or supported by Meta.

Documentation

Acknowledgments

This plugin was inspired by stylex-webpack.

License

MIT — see LICENSE