{"id":15415039,"url":"https://github.com/sukkaw/style9-webpack","last_synced_at":"2025-04-13T15:13:37.886Z","repository":{"id":65238996,"uuid":"588832202","full_name":"SukkaW/style9-webpack","owner":"SukkaW","description":"The another Webpack Plugin for Atomic CSS-in-JS implementation style9","archived":false,"fork":false,"pushed_at":"2024-04-28T06:26:44.000Z","size":694,"stargazers_count":21,"open_issues_count":1,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-13T15:13:32.039Z","etag":null,"topics":["atomic-css","css","css-in-js","typescript","webpack"],"latest_commit_sha":null,"homepage":"https://github.com/johanholmerin/style9","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":"2023-01-14T06:44:18.000Z","updated_at":"2025-02-27T09:52:25.000Z","dependencies_parsed_at":"2024-02-03T18:03:57.807Z","dependency_job_id":"11f26220-c9c5-4433-b623-75d2e59c0231","html_url":"https://github.com/SukkaW/style9-webpack","commit_stats":{"total_commits":51,"total_committers":3,"mean_commits":17.0,"dds":"0.039215686274509776","last_synced_commit":"6910d51f6a45eca0847d514d1df0410314253dd6"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SukkaW%2Fstyle9-webpack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SukkaW%2Fstyle9-webpack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SukkaW%2Fstyle9-webpack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SukkaW%2Fstyle9-webpack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SukkaW","download_url":"https://codeload.github.com/SukkaW/style9-webpack/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248732488,"owners_count":21152852,"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":["atomic-css","css","css-in-js","typescript","webpack"],"created_at":"2024-10-01T17:05:43.318Z","updated_at":"2025-04-13T15:13:37.862Z","avatar_url":"https://github.com/SukkaW.png","language":"TypeScript","funding_links":["https://github.com/sponsors/SukkaW/"],"categories":[],"sub_categories":[],"readme":"# style9-webpack\n\nCreated by Johan Holmerin, [style9](https://github.com/johanholmerin/style9) is a CSS-in-JS compiler inspired by Facebook's [stylex](https://www.youtube.com/watch?v=9JZHodNR184), with near-zero runtime, atomic CSS extraction, and TypeScript support. Framework agnostic.\n\nstyle9-webpack is an alternative webpack plugin for style9.\n\n## Motivation\n\n**ATTENTION! Please please please read this first before you install style9-webpack!**\n\nstyle9 is a CSS-in-JS compiler, which means you will write your CSS in your JavaScript/JSX/TSX. But unlike other CSS-in-JS solutions, style9 provides an AoT Compiler. style9 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. For more details about how style9 works, please check out [style9's documentation](https://github.com/johanholmerin/style9/blob/master/docs/How-it-works.md).\n\nstyle9 does provide a webpack plugin. It uses [`webpack-virtual-modules`](https://github.com/sysgears/webpack-virtual-modules) under the hood. During the compilation, style9 collects your styles and writes collected CSS into virtual modules. `MiniCssExtractPlugin` later will extract those virtual css files.\n\nHowever, `webpack-virtual-modules` [doesn't work well with Next.js](https://github.com/vercel/next.js/issues/44266). Next.js launches multiple webpack compiler instances to compile its server-side and client-side code separately. And `webpack-virtual-modules` just doesn't work when it is being shared between multiple webpack compiler instances.\n\nI start this project as a Proof of Concept, to see if it is possible to make a webpack plugin for style9 that doesn't require `webpack-virtual-modules`. I use the `virtualFileLoader` idea from [Vanilla Extract](https://github.com/vanilla-extract-css/vanilla-extract), another CSS-in-JS compiler. You can find the implementation of Vanilla Extract's `virtualFileLoader` [here](https://github.com/vanilla-extract-css/vanilla-extract/blob/aabb5869a626b7d966814ec8bc322a0392b77561/packages/webpack-plugin/src/virtualFileLoader.ts).\n\n**You most likely want to use style9's built-in webpack plugin instead. It works well for most cases. style9-webpack is just a Proof of Concept.** But if you are using Next.js 13, and you are having trouble with style9's built-in Next.js plugin, you can give style9-webpack a shot.\n\n## Differences\n\nThe main differences between style9's built-in webpack plugin and style9-webpack are as follows:\n\n**style9-webpack loader doesn't have an `inlineLoader` option**\n\nstyle9's built-in webpack loader has an `inlineLoader` option. It allows you to chain other webpack loaders (like `css-loader`) to process the collected virtual css, like this:\n\n```js\nmodule.exports = {\n  module: {\n    rules: [\n      {\n        test: /\\.(tsx|ts|js|mjs|jsx)$/,\n        use: [{\n          loader: Style9Plugin.loader,\n          options: {\n            inlineLoader: `!${MiniCssExtractPlugin.loader}!css-loader`,\n            ...otherStyle9Options\n          }\n        }]\n      }\n      // ...\n    ];\n  });\n}\n```\n\nstyle9-webpack doesn't support this approach. Instead, you will need add an extra rule to provide your loaders:\n\n```js\nmodule.exports = {\n  module: {\n    rules: [\n      {\n        test: /\\.(tsx|ts|js|mjs|jsx)$/,\n        use: [{\n          loader: Style9Plugin.loader,\n          options: {\n            // Now style9-webpack will use \"xxxx.style9.css\" as the virtual css filenames\n            virtualFileName: '[path][name].[hash:base64:7].style9.css',\n            ...otherStyle9Options\n          }\n        }]\n      },\n      // And you create another rule to match the virtual css files. Now you can apply loaders to them.\n      {\n        test: /\\.style9.css$/i,\n        use: [MiniCssExtractPlugin.loader, 'css-loader']\n      },\n      // ...\n    ];\n  });\n}\n```\n\n**style9-webpack doesn't support Gatsby**\n\nYou should use style9's built-in gatsby plugin instead. See [style9's documentation](https://github.com/johanholmerin/style9/blob/master/docs/Bundler-plugins.md#gatsby) for usage with Gatsby.\n\n## Installation\n\n```sh\n# NPM\nnpm i style9-webpack\n# Yarn\nyarn add style9-webpack\n# PNPM\npnpm add style9-webpack\n```\n\n## Usage\n\n### Webpack\n\n```js\n// webpack.config.js\nconst Style9Plugin = require('style9-webpack');\nconst MiniCssExtractPlugin = require('mini-css-extract-plugin');\n\nmodule.exports = {\n  // Collect all styles in a single file - required\n  optimization: {\n    splitChunks: {\n      cacheGroups: {\n        styles: {\n          name: 'styles',\n          type: 'css/mini-extract',\n          chunks: 'all',\n          enforce: true,\n        }\n      }\n    }\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.(tsx|ts|js|mjs|jsx)$/,\n        use: Style9Plugin.loader,\n        options: {\n          virtualFileName: '[path][name].[hash:base64:7].style9.css', // {string?} optional, default is '[path][name].style9.css'\n          parserOptions: {}, // {import('@babel/core').ParserOptions} optional, default is `{ plugins: ['typescript', 'jsx'] }`\n          minifyProperties: process.env.NODE_ENV === 'production', // {boolean?} optional, default is false, recommended to enable this option in production\n          incrementalClassnames: false, // {boolean?} optional, default is false\n        }\n      },\n      {\n        test: /\\.style9.css$/i,\n        use: [MiniCssExtractPlugin.loader, 'css-loader']\n      }\n    ]\n  },\n  plugins: [\n    new Style9Plugin(),\n    new MiniCssExtractPlugin()\n  ]\n};\n```\n\n### Next.js\n\n```js\n// next.config.js\nconst withStyle9 = require('style9-webpack/next');\n\nmodule.exports = withStyle9({\n  parserOptions: {}, // // {import('@babel/core').ParserOptions} optional, default is `{ plugins: ['typescript', 'jsx'] }`\n  minifyProperties: process.env.NODE_ENV === 'production', // {boolean?} optional, default is false, recommended to enable this option in production\n  incrementalClassnames: false, // {boolean?} optional, default is false\n})({\n  // Your Next.js config goes here.\n});\n```\n\n### Next.js (appDir)\n\nCurrently, `style9-webpack/next` doesn't work well with Next.js appDir when \"style9.create\" is used in Server Components, due to a Next.js internal implementation detail. See https://github.com/SukkaW/style9-webpack/issues/1 for more information.\n\nIn the meantime, you can use `style9-webpack/next-appdir` instead. It is a plugin specially designed to workaround the Next.js internal implementation quirk and can work with Next.js 13 beta appDir perfectly.\n\n```js\n// next.config.js\nconst withStyle9 = require('style9-webpack/next-appdir');\n\nmodule.exports = withStyle9({\n  parserOptions: {}, // // {import('@babel/core').ParserOptions} optional, default is `{ plugins: ['typescript', 'jsx'] }`\n  minifyProperties: process.env.NODE_ENV === 'production', // {boolean?} optional, default is false, recommended to enable this option in production\n  incrementalClassnames: false, // {boolean?} optional, default is false\n})({\n  // Your Next.js config goes here.\n});\n```\n\n## Author\n\n**style9-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/style9-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%2Fstyle9-webpack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsukkaw%2Fstyle9-webpack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsukkaw%2Fstyle9-webpack/lists"}