# styled-jsx scopes CSS by stamping a jsx-123 class on every element, and its docs still say v3

> vercel/styled-jsx compiles style jsx tags into unique class names and a small runtime component. The front-page documentation targets v3, while the newest release is v5.1.7 from April 2025.

**vercel/styled-jsx** — Full CSS support for JSX without compromises

- Repository: https://github.com/vercel/styled-jsx
- Website: http://npmjs.com/styled-jsx
- Stars: 7,770 · Forks: 265
- Language: JavaScript
- License: MIT
- Published: 2026-10-08 · Updated: 2026-11-03 · Language: en
- Canonical page: https://hysenlabs.com/projects/vercel-styled-jsx

## The Babel plugin entry is the only setup, and Next.js does it for you

Setup is an install and one plugin line. The install:

```bash
npm install --save styled-jsx
```

Then add styled-jsx/babel to plugins in the Babel configuration:

```json
{
  "plugins": ["styled-jsx/babel"]
}
```

After that, a style jsx tag with CSS in a template literal works inside any component. Under Next.js, none of this is needed: Next.js automatically configures styled-jsx with Babel or swc, so you do not configure it manually.

The README lists options for the plugin, which are covered in a later section. The package also exposes a webpack entry (webpack.js), a macro entry (macro.js) and a css.js helper at the top level of the repository, next to style.js, the runtime module the compiled output imports.

## One paragraph gets the style, and a child component's paragraphs do not

The README's first example makes the scoping promise concrete:

```jsx
export default () => (
  <div>
    <p>only this paragraph will get the style :)</p>

    {/* you can include <Component />s here that include
         other <p>s that don't get unexpected styles! */}

    <style jsx>{`
      p {
        color: red;
      }
    `}</style>
  </div>
)
```

The p selector reaches only paragraphs written in that component's own JSX. A p inside an included child component stays unstyled.

The cost of that isolation shows up the moment you want to style a child from its parent. The README has a FAQ entry titled Styling third parties / child components from the parent, plus one for building a component library. The README's :global() selector, covered below, is its documented way to style third-party components.

## Scoping works by adding a jsx-123 class to every element in the component

The compiled form of the example above is the clearest way to see the mechanism:

```jsx
import _JSXStyle from 'styled-jsx/style'

export default () => (
  <div className="jsx-123">
    <p className="jsx-123">only this paragraph will get the style :)</p>
    <_JSXStyle id="123">{`p.jsx-123 {color: red;}`}</_JSXStyle>
  </div>
)
```

Every element gets the same generated class, and the selector is rewritten to p.jsx-123. The _JSXStyle component from styled-jsx/style is optimized for injecting styles upon render, injecting a component's style only once even when the component appears many times, removing unused styles and keeping track of styles for server-side rendering.

The outer div also gets the class, so you can target the root the way :host works in Shadow DOM. To hit only the host, use a class instead, as in the README's .root example.

## Global styles need the global attribute, and one-off globals need :global()

To skip scoping for a whole block, add global to the tag:

```jsx
export default () => (
  <div>
    <style jsx global>{`
      body {
        background: red;
      }
    `}</style>
  </div>
)
```

The README gives two reasons to prefer this over a plain style tag. You avoid dangerouslySetInnerHTML and its escaping issues with CSS, and you get the de-duping system so global styles are not inserted several times.

For a single selector, :global() works, inspired by css-modules. The README's use case is a third-party component such as react-select, which accepts a custom class through optionClassName. The scoped part of the selector, div, is prefixed, while the :global class stays untouched.

## The optimizeForSpeed option trades devtools editing for injection speed

Four plugin options exist. The first, optimizeForSpeed, switches to a CSS rule injection system based on the CSSOM APIs:

```json
{
  "plugins": [["styled-jsx/babel", { "optimizeForSpeed": true }]]
}
```

In production, where process.env.NODE_ENV is production, this mode is enabled automatically. The warning is that with the option on, source maps cannot be generated and styles cannot be edited through the devtools. A bug that only appears in production can therefore be harder to debug with live CSS edits.

The others have simple defaults. sourceMaps defaults to false. styleModule, the module that transpiled files import, defaults to styled-jsx/style. vendorPrefixes, which turns automatic vendor prefixing on or off, defaults to true.

The README claims a runtime of 3kb gzipped, down from 12kb. That figure is the project's own claim.

## The README documents v3 while the package is at v5.1.7

Near the top, the README states that the code and docs are for v3, which it highly recommends, and sends anyone looking for v2 to the v2 branch. The newest releases are v5.1.7 on 2025-04-30, v5.1.6 on 2024-05-24 and v5.1.5 on 2024-05-24. The package.json version field reads 0.0.0-development, so the version comes from the release tag, not from the file.

The mismatch means you cannot assume every README detail still applies to v5. The Changelog.md at the top level is the place to compare. The last push to the repository was 2026-06-09, and it is not archived.

The build tooling reflects a modernization of the internals: bunchee builds the webpack, index and Babel bundles, pnpm manages the workspace, tests run with ava, and type definitions ship as index.d.ts, css.d.ts, style.d.ts and macro.d.ts.

## Dynamic styles come in three forms, and the README warns about tooling gaps

A component can be customized from outside in three ways: interpolated dynamic props, className toggling and inline style. Any value that comes from the component's render method scope counts as dynamic, so props and state work inside the template literal. The README's example sets a button padding from a prop.

Several limits are named in the table of contents. A warning, unknown jsx prop on the style tag, has its own FAQ entry. So does the question of returning an array of components under React 16. A third entry, Some styles are missing in production, links to a GitHub issue comment instead of an explanation in the README.

The README also has sections for CSS preprocessing via plugins, rendering in tests, syntax highlighting, ESLint and TypeScript. Read those sections in the repository before relying on the tooling.

## Conclusion

Use styled-jsx when you want component-scoped CSS written inside JSX, especially in Next.js, which configures it for you. Skip it if you need a library with recent releases, since v5.1.7 dates from 2025-04-30 and the last push was 2026-06-09. Before adopting, confirm which docs apply, because the README text describes v3.

## FAQ

### How to install styled-jsx?

Run npm install --save styled-jsx, then add styled-jsx/babel to the plugins array in your Babel configuration. Next.js configures it automatically with Babel or swc.

### Does styled-jsx need configuration in Next.js?

No. Next.js automatically configures styled-jsx with Babel or swc, so you do not have to configure it manually.

### What does the optimizeForSpeed option do in styled-jsx?

It enables a CSS rule injection system based on the CSSOM APIs. It is switched on automatically in production, and with it on, source maps cannot be generated and styles cannot be edited through devtools.

### What are the default values of the styled-jsx Babel options?

sourceMaps defaults to false, styleModule defaults to styled-jsx/style, and vendorPrefixes defaults to true.

## Sources

- [License: MIT](https://github.com/vercel/styled-jsx/blob/main/LICENSE)
- [Project website](http://npmjs.com/styled-jsx)
- [README](https://github.com/vercel/styled-jsx/blob/main/README.md)
- [Releases](https://github.com/vercel/styled-jsx/releases)
- [vercel/styled-jsx on GitHub](https://github.com/vercel/styled-jsx)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/vercel-styled-jsx
