Jesse A. Green / notebook

styled-components User Guide

Generated June 2026 from styled-components/styled-components at 051c829

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

styled-components is a CSS-in-JS library for React. You write real CSS in your JavaScript using tagged template literals, and the library generates unique class names, injects the styles into the page, and hands the styled element back to you as an ordinary React component. The result is component-scoped styling with no class-name collisions, full access to your component's props and theme, and automatic critical-CSS handling for server rendering.

This guide is a complete, source-based reference for using styled-components on the web and in React Native. It is written against the source at commit 051c829 (published as package version 6.4.1).

Note

styled-components has no command-line interface and no configuration files. It is a library you import into a React application. Everything below is about the JavaScript/TypeScript API you call from your own code.


Table of Contents

  1. Quick Start
  2. Installation & Requirements
  3. Core Concepts
  4. Creating Styled Components
  5. Passing Props Into Styles
  6. Reusable Styles with css
  7. Animations with keyframes
  8. Global Styles with createGlobalStyle
  9. Theming
  10. attrs — Default & Computed Props
  11. Controlling What Reaches the DOM
  12. Server-Side Rendering
  13. React Native
  14. Package Entry Points
  15. Common Tasks (Recipes)
  16. TypeScript Usage
  17. Troubleshooting
  18. FAQ
  19. API Quick Reference

1. Quick Start

Install the package and start styling a component in under a minute.

npm

npm install styled-components

yarn

yarn add styled-components

pnpm

pnpm add styled-components

Create your first styled component:

import styled from 'styled-components';

// A <button> with styles baked in.
const Button = styled.button`
  background: #0070f3;
  color: white;
  border: none;
  padding: 0.6rem 1.2rem;
  border-radius: 6px;
  font-size: 1rem;
  cursor: pointer;

  &:hover {
    background: #0059c9;
  }
`;

export default function App() {
  return <Button>Click me</Button>;
}

When this renders, styled-components:

  1. Generates a stable, unique class name for Button (e.g. sc-bdvvtL) plus a hashed class for the compiled CSS.
  2. Injects the CSS into a <style data-styled="active"> tag in the document <head>.
  3. Renders a real <button> with those classes applied.
<button class="sc-bdvvtL kFxmL0">Click me</button>

Tip

The & in the template refers to the generated class for this component — exactly like the & in Sass/SCSS. Use it for pseudo-classes (&:hover), nested selectors (& > span), and modifier styles.


2. Installation & Requirements

Install

styled-components ships as a single package on npm. Install it as a regular dependency:

npm install styled-components

Peer dependencies

You must already have React installed. The library declares the following peers:

Peer Required version When you need it
react >= 19.0.0 Always
react-dom >= 19.0.0 Web apps (optional peer)
react-native >= 0.85.0 React Native apps (optional peer)
react-native-reanimated >= 4.0.0 Only for the Reanimated native adapter (optional peer)

The only hard runtime dependency styled-components pulls in itself is csstype (3.2.3), used for CSS property typings.

Important

This version of styled-components requires React 19 or newer. It uses React 19's ref-as-prop model and does not wrap components in React.forwardRef. If you are on React 18 or earlier, use an older release of styled-components.

Node version

For building/SSR, Node >= 16 is supported by the package.

TypeScript

TypeScript types ship inside the package (dist/index.d.ts) — there is no separate @types/styled-components to install for this version. See TypeScript Usage.


3. Core Concepts

A few ideas underpin everything else in this guide.

Styled component : A React component produced by styled that renders an HTML element (or wraps another component) with a fixed set of styles attached. You use it like any other component: <Button>, <Card as="a">, etc.

Tagged template literal : The styled.div`...` syntax is a JavaScript tagged template. The CSS goes between the backticks. You can interpolate values — strings, numbers, functions of props, other styled components, keyframes, and css blocks.

Interpolation : Anything you embed with ${...} inside the template. A function interpolation ${props => ...} runs on every render with the component's props (plus theme), letting styles respond to props dynamically.

Transient prop : A prop whose name starts with $ (e.g. $active). styled-components reads it for styling but never forwards it to the underlying DOM element, so it can't leak into your HTML. See Controlling What Reaches the DOM.

Theme : A plain object made available to every styled component via React context through <ThemeProvider>. Inside styles, read it with ${props => props.theme.x}.

Component selector : Because a styled component's .toString() returns its class selector, you can interpolate one styled component inside another's CSS to target it: `& ${Icon} { color: red; }`.


4. Creating Styled Components

Styling an HTML element

Every standard HTML element is available as a property on styled:

const Title = styled.h1`
  font-size: 2rem;
  font-weight: 700;
`;

const Wrapper = styled.section`
  padding: 2rem;
  background: papayawhip;
`;
<Wrapper>
  <Title>Hello World</Title>
</Wrapper>

Styling another component

Wrap any React component that accepts a className prop:

const StyledLink = styled(RouterLink)`
  color: #0070f3;
  text-decoration: none;

  &:hover {
    text-decoration: underline;
  }
`;

Note

The wrapped component must spread className onto a DOM element for the styles to apply:

const Plain = ({ className, children }) => (
  <div className={className}>{children}</div>
);
const Fancy = styled(Plain)`color: rebeccapurple;`;

Extending an existing styled component

Call styled() on a styled component to inherit its styles and add more:

const Button = styled.button`
  padding: 0.6rem 1.2rem;
  border-radius: 6px;
`;

const PrimaryButton = styled(Button)`
  background: #0070f3;
  color: white;
`;

PrimaryButton carries both the Button class chain and its own — the base styles come first in the cascade, so the extension wins on conflicts.

The polymorphic as prop

Change the rendered element/component at the call site without redefining styles:

const Button = styled.button`
  /* button styles */
`;

// Render an anchor that looks like the button:
<Button as="a" href="/home">Home</Button>

// Render a custom component:
<Button as={RouterLink} to="/home">Home</Button>

There is also forwardedAs, which passes an as prop through to a wrapped styled component rather than consuming it locally — useful when you wrap a styled component that itself supports as.

Referring to other components (component selector)

Interpolate a styled component into CSS to target its rendered elements:

const Icon = styled.svg`
  fill: currentColor;
  transition: fill 0.2s;
`;

const Link = styled.a`
  color: #333;

  &:hover ${Icon} {
    fill: #0070f3;
  }
`;
<Link href="#"><Icon /> Settings</Link>

Warning

The component-selector trick only works with styled components. Interpolating a plain (non-styled) component into CSS throws error #13 (... is not a styled component and cannot be referred to via component selector).


5. Passing Props Into Styles

Function interpolations receive the component's props (with theme merged in) and run on every render.

const Box = styled.div<{ $padding?: number }>`
  padding: ${props => props.$padding ?? 8}px;
`;

<Box $padding={16} />

Conditional styles

const Text = styled.p<{ $muted?: boolean }>`
  color: ${props => (props.$muted ? '#888' : '#111')};
  font-weight: ${props => (props.$muted ? 400 : 600)};
`;

Whole CSS blocks based on a prop

Combine props with the css helper so the interpolated styles are processed correctly (and any nested interpolations keep working):

import styled, { css } from 'styled-components';

const Panel = styled.div<{ $variant: 'info' | 'danger' }>`
  border: 1px solid;
  padding: 1rem;

  ${props =>
    props.$variant === 'danger'
      ? css`
          border-color: #e00;
          background: #fff5f5;
        `
      : css`
          border-color: #0070f3;
          background: #f0f7ff;
        `}
`;

Tip

Use transient props ($-prefixed) for any prop that exists only to drive styling. They will not be forwarded to the DOM, so you avoid React's "unknown prop" warnings. See section 11.


6. Reusable Styles with css

The css helper tags a block of CSS so it can be stored in a variable and reused across components. It also enables interpolation type-checking and is the correct way to interpolate dynamic CSS that itself contains interpolations.

import { css } from 'styled-components';

const truncate = css`
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
`;

const Title = styled.h2`
  ${truncate}
  font-size: 1.25rem;
`;

css accepts a tagged template, a style object, or a function, and it supports the same prop/theme interpolations as styled:

const focusRing = css<{ $color?: string }>`
  &:focus-visible {
    outline: 2px solid ${p => p.$color ?? '#0070f3'};
    outline-offset: 2px;
  }
`;

Important

When you interpolate a function that returns CSS containing further interpolations (e.g. ${rotate} keyframes inside a ${props => ...}), wrap the returned CSS in css\...``. Returning a bare template string instead can trigger error #12 for keyframes.


7. Animations with keyframes

keyframes defines a CSS @keyframes animation with an automatically scoped, collision-free name. Interpolate the returned value into an animation declaration.

import styled, { keyframes } from 'styled-components';

const rotate = keyframes`
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
`;

const Spinner = styled.div`
  width: 24px;
  height: 24px;
  border: 3px solid #ccc;
  border-top-color: #0070f3;
  border-radius: 50%;
  animation: ${rotate} 1s linear infinite;
`;

The same keyframes value can be reused in multiple components; styled-components injects the @keyframes rule once and dedups it.

Caution

Always interpolate keyframes inside a tagged template (styled or css), never into a plain string. Interpolating a keyframes object into an untagged string throws error #12.


8. Global Styles with createGlobalStyle

createGlobalStyle produces a component that injects global, document-level CSS while it is mounted (and removes it on unmount). It does not render any DOM of its own.

import { createGlobalStyle } from 'styled-components';

const GlobalStyle = createGlobalStyle`
  * { box-sizing: border-box; }
  body {
    margin: 0;
    font-family: system-ui, sans-serif;
    background: ${props => props.theme.bg ?? '#fff'};
  }
`;

function App() {
  return (
    <>
      <GlobalStyle />
      {/* rest of app */}
    </>
  );
}

Global styles support props and theming exactly like other styled components.

Warning

Do not pass children to a global style component — it renders nothing and will warn (createGlobalStyle does not render children).

Warning

Avoid @import inside createGlobalStyle. The CSSOM APIs used in production do not handle @import reliably; the library warns about this. Inject font <link> tags in your HTML <head> or via a head-management library instead.


9. Theming

ThemeProvider

Wrap part of your tree in <ThemeProvider theme={...}> to make a theme object available to every styled component below it.

import styled, { ThemeProvider } from 'styled-components';

const theme = {
  colors: { primary: '#0070f3', text: '#111' },
  space: [0, 4, 8, 16, 32],
};

const Title = styled.h1`
  color: ${props => props.theme.colors.primary};
`;

function App() {
  return (
    <ThemeProvider theme={theme}>
      <Title>Themed</Title>
    </ThemeProvider>
  );
}

Nested <ThemeProvider>s merge with the outer theme:

  • On web, the merge is a shallow spread of the inner theme over the outer.
  • On React Native, themes are deep-merged so nested leaves inherit.

You can also pass a function as theme; it receives the outer theme and returns the merged theme:

<ThemeProvider theme={outer => ({ ...outer, mode: 'dark' })}>
  {children}
</ThemeProvider>

Note

If the theme function does not return an object, you get error #7. A missing or non-object theme prop throws error #8 or #14.

Reading the theme: useTheme

import { useTheme } from 'styled-components';

function Sized({ children }) {
  const theme = useTheme();
  return <div style={{ maxWidth: theme.space[4] }}>{children}</div>;
}

Caution

useTheme throws error #18 if there is no <ThemeProvider> ancestor. If you need a tolerant read, use React.useContext(ThemeContext) directly — it returns undefined instead of throwing.

Reading the theme: withTheme (HOC)

For class components or HOC-style code, withTheme injects a theme prop:

import { withTheme } from 'styled-components';

class Chart extends React.Component {
  render() {
    return <svg fill={this.props.theme.colors.primary} />;
  }
}
export default withTheme(Chart);

ThemeConsumer (render prop)

import { ThemeConsumer } from 'styled-components';

<ThemeConsumer>
  {theme => <div style={{ color: theme.colors.text }} />}
</ThemeConsumer>

CSS-variable theming: createTheme

createTheme builds a theme backed by CSS custom properties. It returns an object shaped like your theme, but every leaf value is a var(--prefix-path, fallback) string you can interpolate directly into styles — and it works in React Server Components, where context is unavailable.

import { createTheme, ThemeProvider } from 'styled-components';

const theme = createTheme({
  colors: { primary: '#0070f3', text: '#111' },
});

// In any component (including RSC):
const Card = styled.div`
  color: ${theme.colors.primary};   // → "var(--sc-colors-primary, #0070f3)"
`;

// At your app root, mount the emitted variable declarations:
function Root({ children }) {
  return (
    <ThemeProvider theme={darkValues}>
      <theme.GlobalStyle />
      {children}
    </ThemeProvider>
  );
}

The object returned by createTheme carries these extras:

Property What it is
<your shape> Same shape as input, leaves are var(--…, fallback) refs
.GlobalStyle A component that emits the --var: value; declarations from the active theme
.raw The original theme object you passed in
.vars Same shape, leaves are the bare variable names (e.g. --sc-colors-primary)
.resolve(el?) Client-only: reads the computed variable values off an element (defaults to <html>)

Options:

Option Default Purpose
prefix "sc" Prefix for variable names (--sc-...). Set for isolation across design systems/microfrontends.
selector ":root" Selector the declarations are emitted under. Use ":host" for Shadow DOM/web components.
const theme = createTheme(tokens, { prefix: 'ds', selector: ':host' });
// → :host { --ds-colors-primary: ...; }

Tip

createTheme is the recommended approach when you use React Server Components, because the var(...) strings are plain text and don't depend on React context at render time.


10. attrs — Default & Computed Props

.attrs() attaches default or computed props/attributes to a styled component. It is more expressive than defaultProps and can also widen a wrapped component's prop interface.

Static attrs

const Input = styled.input.attrs({
  type: 'text',
  spellCheck: false,
})`
  border: 1px solid #ccc;
  padding: 0.4rem;
`;

<Input placeholder="Name" />   // renders <input type="text" spellcheck="false" ...>

Computed attrs (function form)

The function receives the resolved props (including theme) and returns attributes to merge in:

const Slider = styled.input.attrs<{ $size?: number }>(props => ({
  type: 'range',
  min: 0,
  max: 100,
  style: { width: (props.$size ?? 100) + 'px' },
}))`
  accent-color: ${p => p.theme.colors.primary};
`;

Note

Attrs are applied in order and chain when you extend components. An explicit undefined prop passed at the call site wins over an attrs-provided value, letting you opt out of an attrs default.

Post-compile attrs with pop / peek

The function form can take a second argument — an accessor over the component's compiled style. This is mainly used to bridge CSS declarations into props for third-party components (e.g. mapping a CSS color onto a native SVG's fill). pop(name) reads and removes a declaration; peek(name) reads without removing. Both also accept a dotted theme path (e.g. 'color.red.500') to read a theme token with full type inference.

const Icon = styled(SvgIcon).attrs((props, ast) => ({
  // move the CSS `color` declaration onto the SVG's `fill` prop
  fill: ast.pop('color', 'black'),
}))`
  color: ${p => p.theme.colors.primary};
`;

11. Controlling What Reaches the DOM

By default, styled-components forwards props to the underlying element. For HTML tags, it filters to valid HTML/SVG attributes (and on* event handlers); for wrapped components, it forwards everything (the component decides). There are three ways to control this.

Any prop whose name starts with $ is used for styling but never forwarded to the DOM:

const Box = styled.div<{ $active: boolean }>`
  opacity: ${p => (p.$active ? 1 : 0.5)};
`;

<Box $active />   // renders <div class="..."> — no `$active` attribute on the DOM

2. Per-component shouldForwardProp via withConfig

const Comp = styled('div').withConfig({
  shouldForwardProp: (prop) => !['hidden', 'size'].includes(prop),
})<{ size: number; hidden: boolean }>`
  width: ${p => p.size}px;
`;

3. App-wide shouldForwardProp via StyleSheetManager

import { StyleSheetManager } from 'styled-components';
import isPropValid from '@emotion/is-prop-valid';

<StyleSheetManager shouldForwardProp={(prop, target) =>
  typeof target === 'string' ? isPropValid(prop) : true
}>
  <App />
</StyleSheetManager>

Tip

In development, forwarding an unknown prop to a DOM tag logs a one-time warning telling you to use a transient prop or a shouldForwardProp filter. Component-level withConfig({ shouldForwardProp }) takes precedence over the StyleSheetManager filter.

StyleSheetManager also configures other injection concerns — see its full prop list in the API Quick Reference and the Admin Guide.


12. Server-Side Rendering

For traditional (non-streaming) SSR, wrap your render in a ServerStyleSheet to collect the critical CSS, then emit it into the HTML you send to the client.

import { renderToString } from 'react-dom/server';
import { ServerStyleSheet } from 'styled-components';

const sheet = new ServerStyleSheet();
try {
  const html = renderToString(sheet.collectStyles(<App />));
  const styleTags = sheet.getStyleTags(); // string of <style> tags
  // Inject `html` and `styleTags` into your page template.
} catch (error) {
  throw error;
} finally {
  sheet.seal();
}

ServerStyleSheet methods:

Method Returns Use
collectStyles(children) Wrapped element Wrap your app so styles are captured
getStyleTags() string Full <style …>…</style> markup
getStyleElement() React element array Style as React element(s) for frameworks
interleaveWithNodeStream(stream) Node stream Streaming SSR (Node only)
seal() void Finalize the sheet (one render cycle per instance)

Caution

A ServerStyleSheet is single-use per render cycle. Reusing it, or calling collectStyles/getStyleTags after consuming styles, throws error #2. interleaveWithNodeStream is Node-only and throws error #3 in the browser.

React Server Components

This version has built-in RSC support: styled components rendered on the server emit their CSS as inline <style> tags automatically, so basic usage works in RSC without ServerStyleSheet. For theming in RSC, prefer createTheme (CSS variables) since React context is not available during server component rendering. The first-party rscPlugin (from styled-components/plugins) supports advanced RSC scenarios — see the Admin Guide.

Note

A known issue (#5760) is that styled.<tag>(fn) parameters can widen to any with @types/react ≤ 18.2.0; use React 19 types. See Troubleshooting.


13. React Native

Import from styled-components/native. The API mirrors the web, with React Native component aliases instead of HTML tags.

import styled from 'styled-components/native';

const Card = styled.View`
  padding: 16px;
  background-color: white;
  border-radius: 8px;
`;

const Label = styled.Text`
  font-size: 14px;
  color: ${p => p.theme.text};
`;

Available component aliases include: View, Text, TextInput, ScrollView, Image, ImageBackground, Pressable, TouchableOpacity, TouchableHighlight, TouchableNativeFeedback, TouchableWithoutFeedback, FlatList, SectionList, VirtualizedList, Modal, Switch, ActivityIndicator, Button, SafeAreaView, StatusBar, KeyboardAvoidingView, RefreshControl, InputAccessoryView. You can also wrap any component: styled(MyComp)`...`.

Note

styled.ScrollView is pinned to flex-shrink: 0 (React Native ships flex-shrink: 1 for ScrollView) so explicit width/height declarations aren't silently overridden inside flex parents.

Native supports modern CSS features

The native engine understands @media, @container (container queries), @supports, pseudo-states (&:hover, &:focus, &:active, &:disabled), attribute selectors (&[aria-pressed='true']), structural selectors (&:nth-child(...), &:has(...)), combinators (>, +, ~), CSS custom properties / var(), and @starting-style transitions.

Native helpers

import {
  css, createTheme, ThemeProvider, useTheme, withTheme, isStyledComponent,
  toStyleSheet,
  useMediaQuery, useBreakpoint, useContainer, useContainerQuery,
  useMediaEnv, matchMedia,
} from 'styled-components/native';

toStyleSheet(css\...`)converts acss` block to a plain React Native style object:

const styles = toStyleSheet(css`background-color: red; padding: 10px;`);
// → { backgroundColor: 'red', paddingTop: 10, ... }

Animations on native

Native animations use React Native's Animated by default. To use Reanimated 4, add a single side-effect import once at your app entry:

import 'styled-components/native/reanimated';

Important

The Reanimated adapter requires react-native-reanimated@^4 (a peer you must install) and the New Architecture (Fabric). If the package can't be resolved, the import throws a clear error at load time.

React Native Web bridge (experimental)

styled-components/native/web-bridge routes styled-components/native consumers running under react-native-web through the web CSS pipeline (hashed class names, CSSOM insertion) instead of building RN style objects that get re-tokenized. It is experimental — see the Admin Guide.


14. Package Entry Points

styled-components publishes several entry points from the one package:

Import path Provides
styled-components Web API: styled, css, keyframes, createGlobalStyle, createTheme, ThemeProvider, useTheme, withTheme, StyleSheetManager, ServerStyleSheet, isStyledComponent, version, types
styled-components/native React Native API (see section 13)
styled-components/native/reanimated Side-effect import enabling the Reanimated 4 animation adapter
styled-components/native/web-bridge Experimental react-native-web bridge
styled-components/plugins rtlPlugin, rscPlugin for use with StyleSheetManager
styled-components/test-utils find, findAll, enzymeFind test helpers

The default styled import also exposes the secondary helpers as properties, so import styled from 'styled-components' lets you use styled.css, styled.keyframes, etc., without separate named imports.


15. Common Tasks (Recipes)

Toggle a style with a boolean prop

const Tab = styled.button<{ $selected?: boolean }>`
  border-bottom: 2px solid ${p => (p.$selected ? '#0070f3' : 'transparent')};
  font-weight: ${p => (p.$selected ? 700 : 400)};
`;

Build a button variant system

import styled, { css } from 'styled-components';

const variants = {
  primary: css`background: #0070f3; color: #fff;`,
  ghost:   css`background: transparent; color: #0070f3;`,
};

const Button = styled.button<{ $variant?: keyof typeof variants }>`
  padding: 0.6rem 1.2rem;
  border-radius: 6px;
  ${p => variants[p.$variant ?? 'primary']}
`;

Media queries

const Grid = styled.div`
  display: grid;
  grid-template-columns: 1fr;

  @media (min-width: 768px) {
    grid-template-columns: repeat(3, 1fr);
  }
`;

Reuse a theme-aware mixin

const card = css`
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  background: ${p => p.theme.surface};
`;

const Panel = styled.section`${card} padding: 1rem;`;
const Modal = styled.div`${card} padding: 2rem;`;

Find a styled component's DOM nodes in tests

import { find, findAll } from 'styled-components/test-utils';

const root = container; // an HTMLElement from your test render
const el = find(root, Button);       // first match
const all = findAll(root, Button);   // NodeList of matches

Set a CSP nonce on injected styles

<StyleSheetManager nonce="r4nd0m">
  <App />
</StyleSheetManager>

A nonce is also auto-detected from <meta name="sc-nonce">, <meta property="csp-nonce">, or the bundler's __webpack_nonce__.

Scope/namespace generated rules

<StyleSheetManager namespace="#my-app">
  <App />
</StyleSheetManager>

Inject styles into an iframe or alternate root

<StyleSheetManager target={iframeDocument.head}>
  <App />
</StyleSheetManager>

16. TypeScript Usage

Types are bundled — no extra @types package for this version.

Typing component props

const Box = styled.div<{ $w: number; $muted?: boolean }>`
  width: ${p => p.$w}px;
  color: ${p => (p.$muted ? '#888' : '#111')};
`;

Typing your theme

Augment the library's DefaultTheme interface so props.theme is fully typed everywhere:

// styled-components.d.ts in your project source
import 'styled-components';

declare module 'styled-components' {
  export interface DefaultTheme {
    colors: { primary: string; text: string };
    space: number[];
  }
}

If it isn't picked up, check compilerOptions.types/include in tsconfig.json.

Enabling the css prop in TypeScript

The css prop is not declared globally by default (it would otherwise appear on everything). Opt in:

// styled-components.d.ts
import type { CSSProp } from 'styled-components';

declare module 'react' {
  interface Attributes {
    css?: CSSProp;
  }
}

Note

Some large component libraries (e.g. antd Button, Mantine) have triggered TypeScript complexity/regression issues in past versions (#5725, #5756, #4350). This version reworked several prop-mapping types to reduce that. If you hit "type instantiation is excessively deep" or OOM during type-checking, ensure you're on React 19 types and the latest release.


17. Troubleshooting

styled-components throws numbered errors. In production the message is a short pointer to the docs; in development you get the full text below. Format: ### Error: ... → Cause → Solution → Prevention.

Error: Cannot create styled-component for component: %s (#1)

  • Cause: You called styled(x) with a falsy/invalid target (e.g. undefined from a bad import).
  • Solution: Verify the component or tag you pass to styled() is defined and imported correctly.
  • Prevention: Check default-vs-named imports of the component you're wrapping.

Error: Can't collect styles once you've consumed a ServerStyleSheet's styles! (#2)

  • Cause: You reused a ServerStyleSheet, or called collectStyles/ getStyleTags after the sheet was already consumed/sealed.
  • Solution: Create a new ServerStyleSheet for every render cycle and call seal() in a finally.
  • Prevention: Never share a sheet instance across requests/renders.

Error: Streaming SSR is only supported in a Node.js environment (#3)

  • Cause: interleaveWithNodeStream was called in the browser.
  • Solution: Only call it on the server.

Error: The StyleSheetManager expects a valid target or sheet prop! (#4)

  • Cause: A falsy target (client) or sheet (server) was passed to StyleSheetManager.
  • Solution: Ensure the DOM node / sheet you pass actually exists when the component mounts.

Error: ThemeProvider: Please return an object from your "theme" prop function (#7)

  • Cause: A function theme prop returned a non-object (null/array/primitive).
  • Solution: Return a plain object: theme={outer => ({ ...outer })}.

Error: ThemeProvider: Please make your "theme" prop an object (#8)

  • Cause: theme was an array or non-object value.
  • Solution: Pass a plain object (or a function returning one).

Error: ThemeProvider: "theme" prop is required (#14)

  • Cause: <ThemeProvider> was rendered without a theme.
  • Solution: Always provide theme.

Error: It seems you are interpolating a keyframe declaration into an untagged string (#12)

  • Cause: A keyframes value was interpolated into a plain string instead of a css/styled template.
  • Solution: Wrap the CSS in the css\...`` helper.

Error: %s is not a styled component and cannot be referred to via component selector (#13)

  • Cause: You interpolated a non-styled component into CSS as a selector.
  • Solution: Only use styled components in component-selector interpolations.

Error: A plugin has been supplied that is not named (#15)

  • Cause: A plugin passed to <StyleSheetManager plugins={[...]}> has no name.
  • Solution: Give each plugin a unique name (e.g. Object.defineProperty(plugin, 'name', { value: 'my-plugin' })).

Error: Reached the limit of how many styled components may be created (#16)

  • Cause: You created more than 1,073,741,824 components — almost always from creating styled components inside render in a loop.
  • Solution: Define styled components at module scope, not inside render.

Error: Accessing useTheme hook outside of a <ThemeProvider> element (#18)

  • Cause: useTheme() was called with no <ThemeProvider> ancestor.
  • Solution: Wrap the tree in <ThemeProvider>, or use React.useContext(ThemeContext) for a tolerant read.

Warning: several instances of styled-components are initialized

  • Cause: More than one copy of styled-components is loaded (duplicate versions in the bundle). Causes broken dynamic styles, theme loss, and rehydration errors.
  • Solution: Deduplicate the dependency (single version) in your lockfile / bundler; ensure libraries share one styled-components instance.

Warning: unknown prop "x" is being sent to the DOM

  • Cause: A non-standard prop is being forwarded to an HTML element.
  • Solution: Rename it to a transient prop ($x) or add a shouldForwardProp filter.

SSR hydration mismatch / class names differ between server and client

  • Cause: Multiple instances of the library, or a build that externalizes styled-components inconsistently (#5737), can cause class-name divergence.
  • Solution: Ensure exactly one styled-components instance is used for both server and client; check nodeExternals/SSR bundling config.

styled(SomeLibButton) rejects all props / parameter becomes any

  • Cause: Old @types/react (#5756, #5760).
  • Solution: Upgrade to React 19 types.

18. FAQ

Q: Do I need a Babel or build plugin? No. styled-components works at runtime with no build step. A build plugin (babel-plugin-styled-components) exists to add stable component IDs and nicer display names, but it is optional and not required for the library to function.

Q: What's the difference between transient props and shouldForwardProp? Transient props ($-prefixed) are the simplest opt-out: they're never forwarded. shouldForwardProp is a programmatic filter for cases where you can't rename the prop (e.g. bridging a third-party prop validator).

Q: How do I share styles between components? Put them in a css\...`` block and interpolate that block into each component.

Q: Can I use object styles instead of strings? Yes — css({...}) and the styled.div({...})-style object syntax are supported; they go through the same pipeline as template literals.

Q: How do I do dark mode? Either swap the theme object passed to <ThemeProvider> (and read props.theme), or use createTheme with CSS variables and toggle the values at the :root selector.

Q: Does it work with React Server Components? Yes. Basic styled components emit inline <style> tags on the server automatically. For theming in RSC, use createTheme (CSS variables), since React context isn't available in server components.

Q: Where did the documentation site go? The full narrative docs live at https://styled-components.com/docs. The in-repository docs only point there; this guide is generated directly from the source code.

Q: How do I name/scope the injected style attribute? The DOM attribute defaults to data-styled. You can override it via the SC_ATTR (or REACT_APP_SC_ATTR) environment variable at build time — see the Admin Guide.

Q: Is styled.xxx available for every HTML element? Yes — every standard HTML element is a property on styled, and every SVG/HTML attribute is recognized for prop forwarding.

Q: How do I change the rendered tag at the usage site? Use the as prop: <Button as="a" href="...">. Use forwardedAs to pass as through to a wrapped styled component.

Q: Can I detect whether something is a styled component? Yes: isStyledComponent(MaybeStyled) returns a boolean.


19. API Quick Reference

Web exports (styled-components)

Export Kind Purpose
styled (default + named) factory Create styled components: styled.tag\`, styled(Comp)```
styled.tag.attrs(...) method Default/computed props (object or function)
styled(...).withConfig(...) method Set displayName, componentId, shouldForwardProp, etc.
css helper Reusable CSS blocks / dynamic CSS / object styles
keyframes helper Scoped @keyframes animations
createGlobalStyle factory Global CSS component
createTheme factory CSS-variable-backed theme (.GlobalStyle, .raw, .vars, .resolve)
ThemeProvider component Provide a theme via context
ThemeConsumer component Render-prop theme access
ThemeContext context Raw theme context (tolerant access)
useTheme hook Read theme (throws if no provider)
withTheme HOC Inject theme prop
StyleSheetManager component Configure injection (see props below)
ServerStyleSheet class Collect critical CSS for SSR
isStyledComponent function Test if a value is a styled component
extractCSS function Extract CSS (advanced/utility)
version string The library version (SC_VERSION)

StyleSheetManager props

Prop Type Purpose
namespace string Prepend a selector to all generated rules
sheet StyleSheet Provide a custom sheet (advanced SSR)
shouldForwardProp (prop, target) => boolean App-wide prop forwarding filter
plugins SCPlugin[] CSS-emission plugins (e.g. rtlPlugin, rscPlugin)
nonce string CSP nonce for injected <style> tags
target HTMLElement | ShadowRoot Alternate node to host styles (e.g. iframe)

Native exports (styled-components/native)

styled (with RN component aliases), css, createTheme, ThemeProvider, ThemeConsumer, ThemeContext, useTheme, withTheme, isStyledComponent, toStyleSheet, matchMedia, useMediaQuery, useBreakpoint, useContainer, useContainerQuery, useMediaEnv, setAnimationDebug, plus NativeStyleContext/ParentContext and related hooks.

Other entry points

styled-components/plugins → rtlPlugin, rscPlugin. styled-components/native/reanimated → side-effect import (Reanimated 4 adapter). styled-components/native/web-bridge → experimental rn-web bridge. styled-components/test-utils → find, findAll, enzymeFind.