{"id":15415058,"url":"https://github.com/sukkaw/stylex-webpack","last_synced_at":"2025-04-19T12:57:44.882Z","repository":{"id":222529012,"uuid":"756761233","full_name":"SukkaW/stylex-webpack","owner":"SukkaW","description":"The another webpack/Next.js Plugin for Facebook StyleX","archived":false,"fork":false,"pushed_at":"2024-12-15T16:24:11.000Z","size":756,"stargazers_count":23,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-16T09:24:45.512Z","etag":null,"topics":["css-in-js","nextjs","stylex","webpack","webpack5"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SukkaW.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-13T09:03:22.000Z","updated_at":"2025-03-12T14:36:13.000Z","dependencies_parsed_at":"2024-04-14T16:39:15.994Z","dependency_job_id":"c6da5a1e-d292-4880-ba18-c0b55b2e23d1","html_url":"https://github.com/SukkaW/stylex-webpack","commit_stats":null,"previous_names":["sukkaw/stylex-webpack"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SukkaW%2Fstylex-webpack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SukkaW%2Fstylex-webpack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SukkaW%2Fstylex-webpack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SukkaW%2Fstylex-webpack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SukkaW","download_url":"https://codeload.github.com/SukkaW/stylex-webpack/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249699496,"owners_count":21312410,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css-in-js","nextjs","stylex","webpack","webpack5"],"created_at":"2024-10-01T17:05:48.225Z","updated_at":"2025-04-19T12:57:44.845Z","avatar_url":"https://github.com/SukkaW.png","language":"TypeScript","funding_links":["https://github.com/sponsors/SukkaW/"],"categories":[],"sub_categories":[],"readme":"# stylex-webpack\n\n[First introduced by Frank Yan at React Conf 2020](https://www.youtube.com/watch?v=9JZHodNR184), [StyleX](https://stylexjs.com/) framework agnostic CSS-in-JS system with near-zero runtime, ahead-of-time compiler, atomic CSS extraction that powers Facebook and Instagram.\n\n## Motivation\n\nstylex offers a CSS-in-JS compiler, allowing you to write CSS in your JavaScript/JSX/TSX. However, unlike other CSS-in-JS solutions that gather and process styles within the browser, stylex will read your source code, collect your style and transform your JS/JSX/TSX, stripping runtime calls as much as possible (making the value of `className` a static string literal), and output CSS elsewhere.\n\nStyleX does provide a webpack plugin. Under the hood, it will traverse through the source code, collect styles, and emit a new CSS asset during the webpack compilation. However, it does come with some limitations:\n\n- StyleX's official Next.js setup requires a `.babelrc` file, which disables Next.js' built-in SWC compiler.\n- StyleX's official Next.js plugin requires a CSS asset to pre-exist so that it can append the extracted CSS to it.\n\nI start this project as a Proof of Concept, to see if it is possible to make a webpack plugin for ststylex that doesn't disable Next.js' SWC compiler. I have already made [a similar webpack plugin for style9](https://github.com/sukkaw/style9-webpack), which is also an AoT atomic CSS-in-JS system that is inspired by StyleX.\n\nUnlike stylex's official webpack plugin, `stylex-webpack` requires you have setup `css-loader` and `MiniCssExtractPlugin` in your webpack configuration, just like your normal CSS based webpack project. `stylex-webpack`'s built-in loader will generate a virtual CSS import containing a dummy CSS rule. This allows the `MiniCssExtractPlugin` to collect those virtual CSS imports and emit a CSS asset, which `stylex-webpack` will later inject the actual extracted CSS into at the `processAssets` stage.\n\n## Installation\n\n```sh\n# npm\nnpm i stylex-webpack\n# Yarn\nyarn add stylex-webpack\n# pnpm\npnpm add stylex-webpack\n```\n\n## Usage\n\n### Webpack\n\n```js\n// webpack.config.js\nconst { StyleXPlugin } = require('stylex-webpack');\nconst MiniCssExtractPlugin = require('mini-css-extract-plugin');\n\nmodule.exports = {\n  module: {\n    rules: [\n      // Just like your normal CSS setup, a css-loader and MiniCssExtractPlugin.loader\n      {\n        test: /\\.css$/i,\n        use: [MiniCssExtractPlugin.loader, 'css-loader']\n      }\n    ]\n  },\n  plugins: [\n    new StyleXPlugin({\n      // stylex-webpack options goes here, see the following section for more details\n    }),\n    new MiniCssExtractPlugin(),\n    new CssMinimizerPlugin()\n    // You can also use `LightningCssMinifyPlugin` from `lightningcss-loader`\n    // to replace CssMinimizerPlugin for faster CSS minification\n    // https://github.com/fz6m/lightningcss-loader\n  ]\n};\n```\n\n### Next.js\n\n```js\n// next.config.js\nconst { withStyleX } = require('stylex-webpack/next');\n\nmodule.exports = withStyleX({\n  // stylex-webpack options goes here, see the following section for more details\n})({\n  // Your Next.js config goes here.\n  reactStrictMode: true\n});\n```\n\n## Options\n\n### webpack\n\n```ts\nnew StyleXPlugin({\n  // stylex-webpack options\n\n  /**\n   * stylex options passed to stylex babel plugin\n   *\n   * @see https://stylexjs.com/docs/api/configuration/babel-plugin/\n   */\n  stylexOption: {\n    dev: process.env.NODE_ENV === 'development',\n    test: process.env.NODE_ENV === 'test'\n    // Check the stylex documentation for more options\n  },\n  /* Specify where stylex will be imported from\n   * This overrides `importSources` in the `stylexOption` above\n   *\n   * @default ['stylex', '@stylexjs/stylex']\n   */\n  stylexImports: ['stylex', '@stylexjs/stylex'],\n  /**\n   * Whether to use CSS layers\n   *\n   * @default false\n   */\n  useCSSLayers?: boolean,\n  /**\n   * Enable other CSS transformation\n   *\n   * Since stylex-webpack's loader only emit virtual CSS imports with dummy rules,\n   * while the actual CSS is injected by the plugin after all loaders, you can not\n   * use postcss-loader + PostCSS plugins. You can manually transform the CSS here.\n   */\n  transformCss(css) {\n    const postcss = require('postcss');\n    const autoprefixer = require('autoprefixer');\n    /**\n     * It is a known issue that stylex won't sort your at-rules and media queries.\n     *\n     * https://github.com/facebook/stylex/issues/455\n     * https://github.com/facebook/stylex/issues/517\n     *\n     * For now, it is recommended to use postcss-sort-media-queries as a workaround.\n     */\n    const sortMediaQueries = require('postcss-sort-media-queries');\n\n    return postcss([\n      autoprefixer({\n        // autoprefixer options\n      }),\n      sortMediaQueries({\n        sort: 'mobile-first'\n      })\n    ]).process(css, { from: undefined }).css;\n\n    // If you don't use custom PostCSS plugins (like `postcss-sort-media-queries`\n    // mentioned above), only downleveling CSS syntax using autoprefixer, you can\n    // also use LightningCSS. It is a Rust-based CSS transformer and minifier that\n    // has built-in downleveling support.\n    const browserslist = require('browserslist');\n    const { transform, browserslistToTargets } = require('lightningcss');\n    return transform({\n      code: Buffer.from(css),\n      targets: browserslistToTargets(browserslist('\u003e= 0.25%'))\n    }).code;\n\n    // If you don't need to transform CSS at all, you can just return the input as-is as well.\n    return css;\n  }\n});\n```\n\n### Next.js\n\n```ts\nwithStyleX({\n  // The same options as the webpack plugin, but with a few differences\n  stylexOption: {\n    /**\n     * You don't have to specify `dev` here. `stylex-webpack` will automatically read\n     * Next.js building mode and set `dev` accordingly.\n     */\n    // dev: process.env.NODE_ENV === 'development',\n  },\n  /**\n   * You don't have to specify `transformCss` here. `stylex-webpack` will automatically\n   * read your PostCSS configuration and apply it here, just like how Next.js does.\n   *\n   * Under the hood, `withStyleX` uses Next.js built-in PostCSS config reader to\n   * maintain the consistency with Next.js' built-in PostCSS support.\n   */\n  // transformCss(css) {}\n})\n```\n\nIt is recommended to use `postcss-sort-media-queries` as a workaround for stylex's known issue with sorting at-rules and media queries. You can configure it in your PostCSS configuration file, and `stylex-webpack` will automatically apply your PostCSS configuration to the extracted CSS just like Next.js' built-in PostCSS support.\n\n```js\n// postcss.config.js\n\n/** @type {Record\u003c'plugins', import('postcss').AcceptedPlugin[]\u003e} */\nmodule.exports = {\n  plugins: [\n    [\n      require.resolve('postcss-sort-media-queries'),\n      {\n        sort: 'mobile-first' // default value\n      }\n    ],\n\n    // Next.js will disable its built-in default PostCSS configuration you\n    // create `postcss.config.js`, which you can add it back:\n\n    /* --- Start of Next.js built-in default PostCSS configuration --- */\n    require.resolve('next/dist/compiled/postcss-flexbugs-fixes'),\n    [\n      require.resolve('next/dist/compiled/postcss-preset-env'),\n      {\n        browsers: ['defaults'],\n        autoprefixer: {\n          // Disable legacy flexbox support\n          flexbox: 'no-2009'\n        },\n        // Enable CSS features that have shipped to the\n        // web platform, i.e. in 2+ browsers unflagged.\n        stage: 3,\n        features: {\n          'custom-properties': false\n        }\n      }\n    ]\n    /* --- End of Next.js built-in default PostCSS configuration --- */\n  ]\n};\n```\n\n## Author\n\n**stylex-webpack** © [Sukka](https://github.com/SukkaW), Released under the [MIT](./LICENSE) License.\u003cbr\u003e\nAuthored and maintained by Sukka with help from contributors ([list](https://github.com/SukkaW/stylex-webpack/graphs/contributors)).\n\n\u003e [Personal Website](https://skk.moe) · [Blog](https://blog.skk.moe) · GitHub [@SukkaW](https://github.com/SukkaW) · Telegram Channel [@SukkaChannel](https://t.me/SukkaChannel) · Twitter [@isukkaw](https://twitter.com/isukkaw) · Mastodon [@sukka@acg.mn](https://acg.mn/@sukka) · Keybase [@sukka](https://keybase.io/sukka)\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/sponsors/SukkaW/\"\u003e\n    \u003cimg src=\"https://sponsor.cdn.skk.moe/sponsors.svg\"/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsukkaw%2Fstylex-webpack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsukkaw%2Fstylex-webpack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsukkaw%2Fstylex-webpack/lists"}