{"id":13422458,"url":"https://github.com/kriasoft/isomorphic-style-loader","last_synced_at":"2025-05-13T19:07:06.696Z","repository":{"id":44163182,"uuid":"46555028","full_name":"kriasoft/isomorphic-style-loader","owner":"kriasoft","description":"CSS style loader for Webpack that is optimized for isomorphic (universal) web apps.","archived":false,"fork":false,"pushed_at":"2024-12-04T17:09:09.000Z","size":219,"stargazers_count":1270,"open_issues_count":86,"forks_count":144,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-05-08T02:23:45.352Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://reactstarter.com","language":"JavaScript","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/kriasoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","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,"zenodo":null}},"created_at":"2015-11-20T10:20:03.000Z","updated_at":"2025-04-09T20:09:16.000Z","dependencies_parsed_at":"2025-04-12T01:54:04.499Z","dependency_job_id":"ea17da3e-ff14-4962-9a19-60f027e7e57d","html_url":"https://github.com/kriasoft/isomorphic-style-loader","commit_stats":{"total_commits":90,"total_committers":33,"mean_commits":2.727272727272727,"dds":0.6222222222222222,"last_synced_commit":"f30bbe778200424b09f0272746f656990773e9c6"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kriasoft%2Fisomorphic-style-loader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kriasoft%2Fisomorphic-style-loader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kriasoft%2Fisomorphic-style-loader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kriasoft%2Fisomorphic-style-loader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kriasoft","download_url":"https://codeload.github.com/kriasoft/isomorphic-style-loader/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253736106,"owners_count":21955786,"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":[],"created_at":"2024-07-30T23:00:45.449Z","updated_at":"2025-05-13T19:07:06.649Z","avatar_url":"https://github.com/kriasoft.png","language":"JavaScript","funding_links":[],"categories":["Code Design","Uncategorized","JavaScript"],"sub_categories":["Isomorphic Apps","Uncategorized"],"readme":"\u003cimg width=\"150\" height=\"150\" align=\"right\" src=\"https://raw.githubusercontent.com/kriasoft/isomorphic-style-loader/8fe56ef8fba794e00bfbc9b6d731edf0f572d4e7/logo.png\" /\u003e\n\n# Isomorphic CSS style loader for [Webpack](http://webpack.github.io)\n\n[![NPM version](https://img.shields.io/npm/v/isomorphic-style-loader.svg)](https://www.npmjs.com/package/isomorphic-style-loader)\n[![NPM downloads](https://img.shields.io/npm/dw/isomorphic-style-loader.svg)](https://www.npmjs.com/package/isomorphic-style-loader)\n[![Library Size](https://img.shields.io/github/size/kriasoft/isomorphic-style-loader/src/withStyles.js.svg)](https://bundlephobia.com/result?p=isomorphic-style-loader)\n[![Online Chat](https://img.shields.io/discord/643523529131950086?label=Chat)](https://discord.gg/UFkeXwsARY)\n\nCSS style loader for Webpack that works similarly to\n[style-loader](https://github.com/webpack/style-loader), but is optimized for\n[critical path CSS](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/)\nrendering and also works great in the context of\n[isomorphic apps](http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/).\nIt provides two helper methods on to the `styles` object - `._insertCss()`\n(injects CSS into the DOM) and `._getCss()` (returns a CSS string).\n\nSee [getting started](#getting-started) \u0026nbsp;|\u0026nbsp; [changelog](CHANGELOG.md) \u0026nbsp;|\u0026nbsp;\nJoin [#isomorphic-style-loader](https://discord.gg/UFkeXwsARY)\nchat room on Discord to stay up to date\n\n## How to Install\n\n```bash\n$ npm install isomorphic-style-loader --save-dev\n```\n\n## Getting Started\n\n**Webpack configuration:**\n\n```js\nmodule.exports = {\n  /* ... */\n  module: {\n    rules: [\n      {\n        test: /\\.css$/,\n        use: [\n          'isomorphic-style-loader',\n          {\n            loader: 'css-loader',\n            options: {\n              importLoaders: 1\n            }\n          },\n          'postcss-loader'\n        ]\n      }\n    ]\n  }\n  /* ... */\n}\n```\n\n**Note**: Configuration is the same for both client-side and server-side bundles. For more\ninformation visit https://webpack.js.org/configuration/module/.\n\n**React component example:**\n\n```css\n/* App.css */\n.root { padding: 10px }\n.title { color: red }\n```\n\n```js\n/* App.js */\nimport React from 'react'\nimport withStyles from 'isomorphic-style-loader/withStyles'\nimport s from './App.scss'\n\nfunction App(props, context) {\n  return (\n    \u003cdiv className={s.root}\u003e\n      \u003ch1 className={s.title}\u003eHello, world!\u003c/h1\u003e\n    \u003c/div\u003e\n  )\n}\n\nexport default withStyles(s)(App) // \u003c--\n```\n\n**P.S.**: It works great with [CSS Modules](https://github.com/css-modules/css-modules)!\nJust decorate your React component with the\n[withStyles](https://github.com/kriasoft/isomorphic-style-loader/blob/master/src/withStyles.js)\nhigher-order component, and pass a function to your React app via `insertCss`\ncontext variable (see [React's context API](https://reactjs.org/docs/context.html))\nthat either calls `styles._insertCss()` on a client or `styles._getCss()`\non the server. See server-side rendering example below:\n\n```js\nimport express from 'express'\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport StyleContext from 'isomorphic-style-loader/StyleContext'\nimport App from './App.js'\n\nconst server = express()\nconst port = process.env.PORT || 3000\n\n// Server-side rendering of the React app\nserver.get('*', (req, res, next) =\u003e {\n  const css = new Set() // CSS for all rendered React components\n  const insertCss = (...styles) =\u003e styles.forEach(style =\u003e css.add(style._getCss()))\n  const body = ReactDOM.renderToString(\n    \u003cStyleContext.Provider value={{ insertCss }}\u003e\n      \u003cApp /\u003e\n    \u003c/StyleContext.Provider\u003e\n  )\n  const html = `\u003c!doctype html\u003e\n    \u003chtml\u003e\n      \u003chead\u003e\n        \u003cscript src=\"client.js\" defer\u003e\u003c/script\u003e\n        \u003cstyle\u003e${[...css].join('')}\u003c/style\u003e\n      \u003c/head\u003e\n      \u003cbody\u003e\n        \u003cdiv id=\"root\"\u003e${body}\u003c/div\u003e\n      \u003c/body\u003e\n    \u003c/html\u003e`\n  res.status(200).send(html)\n})\n\nserver.listen(port, () =\u003e {\n  console.log(`Node.js app is running at http://localhost:${port}/`)\n})\n```\n\nIt should generate an HTML output similar to this one:\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003ctitle\u003eMy Application\u003c/title\u003e\n    \u003cscript async src=\"/client.js\"\u003e\u003c/script\u003e\n    \u003cstyle type=\"text/css\"\u003e\n      .App_root_Hi8 { padding: 10px }\n      .App_title_e9Q { color: red }\n    \u003c/style\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cdiv id=\"root\"\u003e\n      \u003cdiv class=\"App_root_Hi8\"\u003e\n        \u003ch1 class=\"App_title_e9Q\"\u003eHello, World!\u003c/h1\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\nRegardless of how many styles components there are in the `app.js` bundle,\nonly critical CSS is going to be rendered on the server inside the `\u003chead\u003e`\nsection of HTML document. Critical CSS is what actually used on the\nrequested web page, effectively dealing with\n[FOUC](https://en.wikipedia.org/wiki/Flash_of_unstyled_content)\nissue and improving client-side performance.\nCSS of the unmounted components will be removed from the DOM.\n\nThen on client-side use [hydrate](https://reactjs.org/docs/react-dom.html#hydrate)\nto make your markup interactive:\n\n```js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport StyleContext from 'isomorphic-style-loader/StyleContext'\nimport App from './App.js'\n\nconst insertCss = (...styles) =\u003e {\n  const removeCss = styles.map(style =\u003e style._insertCss())\n  return () =\u003e removeCss.forEach(dispose =\u003e dispose())\n}\n\nReactDOM.hydrate(\n  \u003cStyleContext.Provider value={{ insertCss }}\u003e\n    \u003cApp /\u003e\n  \u003c/StyleContext.Provider\u003e,\n  document.getElementById('root')\n)\n```\n\n**React Hooks Support:**\n\nYou can also use `useStyles` inside your React Functional Components, instead of using `withStyles`.\nPlease note that you still need to pass `insertCss` function to `StyleContext.Provider` from top of the tree.\n\n```js\nimport React from 'react'\nimport useStyles from 'isomorphic-style-loader/useStyles'\nimport s from './App.scss'\n\nconst App = (props) =\u003e {\n  useStyles(s);\n  return (\n    \u003cdiv className={s.root}\u003e\n      \u003ch1 className={s.title}\u003eHello, world!\u003c/h1\u003e\n    \u003c/div\u003e\n  )\n};\n\nexport default App;\n```\n\n## Related Projects\n\n* [React Starter Kit](https://github.com/kriasoft/react-starter-kit) —\n  Isomorphic web app boilerplate (Express.js, React, Relay)\n* [Node.js API Starter](https://github.com/kriasoft/nodejs-api-starter) —\n  Project tempalte for building GraphQL API backends\n\n## License\n\nThe MIT License © 2015-present Kriasoft ([@kriasoft](https://twitter.com/kriasoft)).\nAll rights reserved.\n\n---\nMade with ♥ by\nKonstantin Tarkus ([@koistya](https://twitter.com/koistya), [blog](https://medium.com/@tarkus)),\nVladimir Kutepov ([frenzzy](https://github.com/frenzzy))\nand [contributors](https://github.com/kriasoft/isomorphic-style-loader/graphs/contributors)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkriasoft%2Fisomorphic-style-loader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkriasoft%2Fisomorphic-style-loader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkriasoft%2Fisomorphic-style-loader/lists"}