Isomorphic Style Loader
raw JSON → 5.4.0 verified Sat Apr 25 auth: no javascript
Webpack loader for CSS that optimizes critical path rendering and supports isomorphic (universal) React apps. Current stable version is 5.4.0, released April 2022. Works like style-loader but allows server-side collection of CSS strings via _getCss() and client-side injection via _insertCss(). Uses React Context API (StyleContext) with insertCss callback. Requires React 16.8+ and css-loader. Features withStyles HOC and useStyles hook for React components. Alternative to style-loader when SSR is needed.
Common errors
error Module not found: Error: Can't resolve 'isomorphic-style-loader' ↓
cause Forgetting to install the package or incorrect import path.
fix
Run 'npm install isomorphic-style-loader --save-dev' and ensure import uses correct subpath, e.g., 'isomorphic-style-loader/withStyles'.
error TypeError: styles._getCss is not a function ↓
cause Using the style object incorrectly – likely imported from style-loader instead of isomorphic-style-loader.
fix
Ensure the webpack rule uses 'isomorphic-style-loader' and not 'style-loader'. The style object has _getCss and _insertCss methods.
error Warning: Failed context type: The context `insertCss` is marked as required in `withStyles`, but its value is `undefined`. ↓
cause Missing StyleContext.Provider or insertCss callback not passed.
fix
Wrap your app in <StyleContext.Provider value={{ insertCss: ... }}> with a valid insertCss function.
error Invariant Violation: withStyles requires a React component ↓
cause Calling withStyles(styles) without wrapping a React component.
fix
Use withStyles(styles)(Component) or withStyles(styles)(React.forwardRef(...)).
Warnings
breaking Upgraded React Context API in v5, breaking older withStyles usage from 'isomorphic-style-loader/lib/withStyles'. ↓
fix Use import from 'isomorphic-style-loader/withStyles' (without /lib/) and wrap app in StyleContext.Provider.
breaking React moved to peer dependencies in v5.2.0-beta.1; earlier versions bundled React. ↓
fix Ensure react and react-dom are installed as regular dependencies or peer dependencies.
gotcha Default export from 'isomorphic-style-loader' is the Webpack loader function, not a React utility. Importing 'isomorphic-style-loader' as a module will not give you withStyles. ↓
fix Always use subpath imports: 'isomorphic-style-loader/withStyles', 'isomorphic-style-loader/useStyles', etc.
gotcha Browser usage without SSR: if not using StyleContext, styles won't be injected because insertCss is not called. ↓
fix In client-side only builds, ensure StyleContext provider is set up with a insertCss function that calls styles._insertCss().
deprecated HMR (Hot Module Replacement) now output on demand; old behavior may have been automatically injecting. ↓
fix Check documentation for configuring HMR in webpack; no breaking change but behavior differs.
Install
npm install isomorphic-style-loader yarn add isomorphic-style-loader pnpm add isomorphic-style-loader Imports
- withStyles wrong
import withStyles from 'isomorphic-style-loader'correctimport withStyles from 'isomorphic-style-loader/withStyles' - useStyles wrong
import { useStyles } from 'isomorphic-style-loader'correctimport useStyles from 'isomorphic-style-loader/useStyles' - StyleContext wrong
import { StyleContext } from 'isomorphic-style-loader'correctimport StyleContext from 'isomorphic-style-loader/StyleContext'
Quickstart
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'isomorphic-style-loader',
{ loader: 'css-loader', options: { importLoaders: 1, modules: true } },
'postcss-loader'
]
}
]
}
};
// App.js
import React from 'react';
import withStyles from 'isomorphic-style-loader/withStyles';
import s from './App.css';
function App() {
return <div className={s.root}><h1>Hello</h1></div>;
}
export default withStyles(s)(App);
// server.js
import express from 'express';
import React from 'react';
import ReactDOM from 'react-dom/server';
import StyleContext from 'isomorphic-style-loader/StyleContext';
import App from './App.js';
const server = express();
server.get('*', (req, res) => {
const css = new Set();
const insertCss = (...styles) => styles.forEach(style => css.add(style._getCss()));
const body = ReactDOM.renderToString(
<StyleContext.Provider value={{ insertCss }}>
<App />
</StyleContext.Provider>
);
const html = `<!DOCTYPE html><html><head><style>${[...css].join('')}</style></head><body><div id="root">${body}</div></body></html>`;
res.send(html);
});
server.listen(3000);