Tooling

Vite

Vite is the recommended build tool for new React projects. styled-components works with Vite out of the box, but adding a compiler plugin enables server-side rendering support, better debugging with component display names, and CSS minification.

With SWC (recommended)

The fastest setup uses the SWC-based React plugin with the styled-components SWC plugin:

npm install --save-dev @vitejs/plugin-react-swc @swc/plugin-styled-components
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react-swc';


export default defineConfig({
  plugins: [
    react({
      plugins: [
        ['@swc/plugin-styled-components', {
          displayName: true,
          ssr: true,
        }],
      ],
    }),
  ],
});
Note

The SWC plugin version must be compatible with the SWC core version bundled in @vitejs/plugin-react-swc. If you encounter Wasm errors, check the plugin's compatibility table.

With Babel

If your project already uses Babel plugins, you can use the Babel-based React plugin instead:

npm install --save-dev @vitejs/plugin-react babel-plugin-styled-components
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';


export default defineConfig({
  plugins: [
    react({
      babel: {
        plugins: [
          ['babel-plugin-styled-components', {
            displayName: true,
            ssr: true,
            pure: true,
          }],
        ],
      },
    }),
  ],
});
Note

@vitejs/plugin-react v6+ (Vite 8) removed Babel as a built-in dependency. If you are on v6+, use the SWC approach above or add @rolldown/plugin-babel separately.

SSR with Vite

For server-side rendering with Vite (e.g., using Vike), use styled-components' ServerStyleSheet in your server entry:

// entry-server.tsx
import { renderToString } from 'react-dom/server';
import { ServerStyleSheet } from 'styled-components';
import App from './App';


export function render() {
  const sheet = new ServerStyleSheet();
  try {
    const html = renderToString(sheet.collectStyles(<App />));
    const styleTags = sheet.getStyleTags();
    return { html, styleTags };
  } finally {
    sheet.seal();
  }
}

If you use Vike (formerly vite-plugin-ssr), the vike-react-styled-components extension handles style collection automatically.

SWC Plugin

This plugin adds support for server-side rendering, minification of styles, and better debugging experience when using styled-components with the SWC compiler.

Usage

First, install the @swc/plugin-styled-components and @swc/core packages:

npm install --save-dev @swc/plugin-styled-components @swc/core

Then, add the plugin to your .swcrc configuration file:

{
  "jsc": {
    "experimental": {
      "plugins": [
        [
          "@swc/plugin-styled-components",
          {
            "displayName": true,
            "ssr": true
          }
        ]
      ]
    }
  }
}

Options

  • displayName:
    • Description: Enhances the attached CSS class name on each component with richer output to help identify your components in the DOM without React DevTools. It also allows you to see the component's displayName in React DevTools.
    • Type: Boolean
    • Default: true
    • Values: true or false
  • ssr:
    • Description: Adds a unique identifier to every styled component to avoid checksum mismatches due to different class generation on the client and on the server. Helps in server-side rendering (SSR).
    • Type: Boolean
    • Default: true
    • Values: true or false
  • fileName:
    • Description: Controls whether the displayName of a component will be prefixed with the filename or solely the component name.
    • Type: Boolean
    • Default: true
    • Values: true or false
  • meaninglessFileNames:
    • Description: Allows customizing the list of file names that are not relevant to the description of a styled component's functionality. Uses directory names instead.
    • Type: Array of strings
    • Default: ["index", "styles"]
    • Values: Any array of strings representing meaningless file names.
  • minify:
    • Description: Minifies your CSS by removing all whitespace and comments. Also transpiles tagged template literals to a smaller representation.
    • Type: Boolean
    • Default: true
    • Values: true or false
  • transpileTemplateLiterals:
    • Description: Transpiles styled-components tagged template literals to a smaller representation. Helps reduce bundle size.
    • Type: Boolean
    • Default: true
    • Values: true or false
  • pure:
    • Description: Enables a feature called "pure annotation" to aid dead code elimination process on styled components.
    • Type: Boolean
    • Default: false
    • Values: true or false
  • namespace:
    • Description: Ensures that your class names will be unique, useful when working with micro-frontends where class name collisions can occur.
    • Type: String
    • Default: undefined
    • Values: Any string representing the desired namespace.

Server-side rendering

By adding a unique identifier to every styled component, this plugin avoids checksum mismatches due to different class generation on the client and on the server. If you don't use this plugin and try to server-side render styled components, React will complain with an HTML attribute mismatch warning during rehydration.

You can disable this feature by setting the ssr option to false:

{
  "jsc": {
    "experimental": {
      "plugins": [
        [
          "@swc/plugin-styled-components",
          {
            "ssr": false
          }
        ]
      ]
    }
  }
}

Better Debugging

This option enhances the attached CSS class name on each component with richer output to help identify your components in the DOM without React DevTools. It also allows you to see the component's displayName in React DevTools.

If you don't need this feature, you can disable it by setting the displayName option to false:

{
  "jsc": {
    "experimental": {
      "plugins": [
        [
          "@swc/plugin-styled-components",
          {
            "displayName": false
          }
        ]
      ]
    }
  }
}

Control the components displayName

By default, the displayName of a component will be prefixed with the filename in order to make the component name as unique as possible.

You can force the component displayName to be solely the component name by disabling the fileName option:

{
 "jsc": {
   "experimental": {
     "plugins": [
       [
         "@swc/plugin-styled-components",
         {
           "fileName": false
         }
       ]
     ]
   }
 }
}

Control which file names are meaningless

A common pattern is to put components in Button/index.jsx instead of Button.jsx. By default, if the fileName option is set to true, the plugin will generate the displayName using the directory name (<button class="Button-asdf123 asdf123" />) instead of the file name (<button class="index-asdf123 asdf123" />), because the former provides more information.

The meaninglessFileNames option allows you to customize the list of file names that are not relevant to the description of a styled component's functionality, and hence the directory name should be used instead:

{
 "jsc": {
   "experimental": {
     "plugins": [
       [
         "@swc/plugin-styled-components",
         {
           "meaninglessFileNames": ["index", "styles"]
         }
       ]
     ]
   }
 }
}

Minification

This plugin minifies your CSS by removing all whitespace and comments. It also transpiles tagged template literals to a smaller representation, keeping valuable bytes out of your bundles.

If desired, you can disable this behavior by setting the minify option to false:

{
 "jsc": {
   "experimental": {
     "plugins": [
       [
         "@swc/plugin-styled-components",
         {
           "minify": false,
           "transpileTemplateLiterals": false
         }
       ]
     ]
   }
 }
}

Dead Code Elimination

Due to how styled components are transpiled and constructed, by default, minifiers cannot properly perform dead code elimination on them because they are assumed to have side effects. However, there is a feature that can be enabled to aid this process called "pure annotation".

{
 "jsc": {
   "experimental": {
     "plugins": [
       [
         "@swc/plugin-styled-components",
         {
           "pure": true
         }
       ]
     ]
   }
 }
}

Template String Transpilation

Similar to the Babel plugin, this plugin transpiles styled-components tagged template literals to a smaller representation than what SWC normally creates. This helps reduce the bundle size.

You can disable this feature by setting the transpileTemplateLiterals option to false:

{
 "jsc": {
   "experimental": {
     "plugins": [
       [
         "@swc/plugin-styled-components",
         {
           "transpileTemplateLiterals": false
         }
       ]
     ]
   }
 }
}

Namespace

The namespace option ensures that your class names will be unique, which is handy when working with micro-frontends where class name collisions can occur.

To enable this behavior, set the namespace option in your configuration:

{
 "jsc": {
   "experimental": {
     "plugins": [
       [
         "@swc/plugin-styled-components",
         {
           "namespace": "my-app"
         }
       ]
     ]
   }
 }
}

Babel Plugin

This plugin adds support for server-side rendering, minification of styles, and a nicer debugging experience.

Usage

Install the babel-plugin first:

npm install --save-dev babel-plugin-styled-components

Then add it to your babel configuration like so:

Note

⚠️ The plugin call order in your .babelrc file matters. If you're using the env property in your babel configuration, then putting this plugin into the plugins array won't suffice. Instead it needs to be put into each env's plugins array to maintain it being executed first. See this for more information.

{
  "plugins": ["babel-plugin-styled-components"]
}

Server-side rendering

By adding a unique identifier to every styled component, this plugin avoids checksum mismatches due to different class generation on the client and on the server. If you do not use this plugin and try to server-side render styled-components React will complain with an HTML attribute mismatch warning during rehydration.

You can disable it if necessary with the ssr option:

{
  "plugins": [
    [
      "babel-plugin-styled-components",
      {
        "ssr": false
      }
    ]
  ]
}

Better debugging

This option enhances the attached CSS class name on each component with richer output to help identify your components in the DOM without React DevTools. In your page source you'll see: <button class="Button-asdf123 asdf123" /> instead of just <button class="asdf123" />.

It also allows you to see the component's displayName in React DevTools. For example, consider writing a styled component that renders a button element, called MyButton. It will normally show up in DevTools as styled.button, but with the displayName option enabled, it has the name you gave it: MyButton.

This makes it easier to find your components and to figure out where they live in your app.

If you don't need this feature, you can disable it with the displayName option:

{
  "plugins": [
    [
      "babel-plugin-styled-components",
      {
        "displayName": false
      }
    ]
  ]
}

Control the components displayName

By default, the displayName of a component will be prefixed with the filename in order to make the component name as unique as possible.

You can force the component displayName to be solely the component name by disabling the fileName option:

{
  "plugins": [
    [
      "babel-plugin-styled-components",
      {
        "fileName": false
      }
    ]
  ]
}

One example where you might want to do this is testing components with React Testing Library. If you use snapshot tests or other tools that reference component display names, keeping them short can improve readability. If you do want this for testing only, make sure to add this only under your test environment.

Control which file names are meaningless

A common pattern is to put components in Button/index.jsx instead of Button.jsx. By default, if the fileName option is set to true, the plugin will generate the display name using the directory name (<button class="Button-asdf123 asdf123" />) instead of the file name (<button class="index-asdf123 asdf123" />), because the former provides more information.

The meaninglessFileNames option allows to customize the list of file names that are not relevant to the description of a styled component's functionality, and hence the directory name should be used instead:

{
  "plugins": [
    [
      "babel-plugin-styled-components",
      {
        "meaninglessFileNames": ["index", "styles"]
      }
    ]
  ]
}

For example, adding styles to the list would enable you to store your styled components in a Button/styles.js file.

This option defaults to ["index"].

If either fileName or displayName are set to false, this option has no effect.

Minification

Two types of minifications are performed by this plugin: one removes all whitespace & comments from your CSS and the other transpiles tagged template literals, keeping valuable bytes out of your bundles.

If desired, you can disable this behavior via babel configuration:

{
  "plugins": [
    ["babel-plugin-styled-components", {
      "minify": false,
      "transpileTemplateLiterals": false
    }]
  ]
}

Dead Code Elimination

Due to how styled components are transpiled and constructed, by default minifiers cannot properly perform dead code elimination on them because they are assumed to have side effects. However, there is a feature that can be enabled to aid this process called "pure annotation".

{
  "plugins": [
    ["babel-plugin-styled-components", {
      "pure": true
    }]
  ]
}

It utilizes a babel helper to tag each styled component and library helper with the #__PURE__ JS comment that some minifiers use to overcome the aforementioned issue.

Template String Transpilation

This plugin transpiles styled-components tagged template literals down to a smaller representation than what Babel normally creates.

Wait, transpiling tagged template literals? Doesn't Babel do this natively? 🤔 If you're using @babel/preset-env and targeting browsers that don't natively support tagged template literals, Babel's standard transform produces verbose output to meet specification requirements.

Here's an example of the standard Babel-transpiled output:

var _templateObject = _taggedTemplateLiteral(['width: 100%;'], ['width: 100%;'])
function _taggedTemplateLiteral(strings, raw) {
  return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } }))
}
var Simple = _styledComponents2.default.div(_templateObject)

styled-components does not require full spec compatibility. Our Babel plugin will transpile template literals attached to styled components to a slightly different, smaller form which still works in older browsers but has a much smaller footprint.

Here's the same example with the styled-components Babel plugin and transpileTemplateLiterals: true:

var Simple = _styledComponents2.default.div(['width: 100%;'])

The plugin is also smart enough to not modify tagged template literals belonging to other libraries and use cases:

// Following will be converted:
styled.div``
keyframe``
css```some text` // But this will not be converted:


// Here the outer template literal will be converted
// because it's attached to the component factory,
// but the inner template literals will not be touched:
styled.div`
  color: ${light ? `white` : `black`};
`

You can disable this feature with the transpileTemplateLiterals option:

{
  "plugins": [
    [
      "babel-plugin-styled-components",
      {
        "transpileTemplateLiterals": false
      }
    ]
  ]
}

Read more about Tagged Template Literals in our dedicated section explaining them.

Namespace

The namespace will ensure that your class names will be unique; this setting is handy when you are working with micro frontends where class name collision can occur.

If desired, you can enable this behavior via babel configuration:

{
  "plugins": [
    ["babel-plugin-styled-components", {
      "namespace": "my-app"
    }]
  ]
}

Here's an example of the transpiled code processed with namespace enabled:

_styledComponents2.default.div.withConfig({
  displayName: 'code__before',
  componentId: 'my-app__sc-3rfj0a-1',
})(['color:blue;'])

Testing

jest-styled-components provides utilities for testing styled-components with Jest and Vitest. It offers meaningful snapshot output and the toHaveStyleRule matcher for asserting style rules.

Installation

npm install --save-dev jest-styled-components

Import it once in your test setup file to register the snapshot serializer and matchers globally:

// jest.config.js
module.exports = {
  setupFilesAfterEnv: ['jest-styled-components'],
};

Or for Vitest:

// vitest.config.ts
import { defineConfig } from 'vitest/config';


export default defineConfig({
  test: {
    setupFiles: ['jest-styled-components'],
    environment: 'jsdom',
  },
});

Testing with React Testing Library

React Testing Library is the recommended way to test styled-components. Query elements by role, text, or test ID, then assert styles with toHaveStyleRule.

Themed components

Create a custom render wrapper that includes your ThemeProvider:

// test-utils.tsx
import { render, RenderOptions } from '@testing-library/react';
import { ThemeProvider } from 'styled-components';
import { theme } from './theme';


function Providers({ children }: { children: React.ReactNode }) {
  return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
}


const customRender = (
  ui: React.ReactElement,
  options?: Omit<RenderOptions, 'wrapper'>
) => render(ui, { wrapper: Providers, ...options });


export * from '@testing-library/react';
export { customRender as render };

Then use it in your tests:

import { render, screen } from './test-utils';
import 'jest-styled-components';


const Button = styled.button<{ $primary?: boolean }>`
  background: ${props => props.$primary ? '#BF4F74' : '#ccc'};
`;


test('renders primary styles', () => {
  render(<Button $primary>Click</Button>);
  expect(screen.getByText('Click')).toHaveStyleRule('background', '#BF4F74');
});

toHaveStyleRule

The toHaveStyleRule matcher checks CSS rules injected by styled-components into the stylesheet. It accepts a property name, expected value (string or RegExp), and an optional options object for media queries and pseudo-classes:

import { render, screen } from '@testing-library/react';
import 'jest-styled-components';


const Button = styled.button`
  color: red;
  @media (max-width: 640px) {
    &:hover {
      color: green;
    }
  }
`;


test('applies styles and media queries', () => {
  render(<Button>Click</Button>);
  const button = screen.getByText('Click');


  expect(button).toHaveStyleRule('color', 'red');
  expect(button).toHaveStyleRule('color', 'green', {
    media: '(max-width: 640px)',
    modifier: ':hover',
  });
});
Note

Use toHaveStyleRule (from jest-styled-components) rather than toHaveStyle (from @testing-library/jest-dom) for styled-components. In jsdom, getComputedStyle does not resolve styles from <style> tags, so toHaveStyle will not see styled-components CSS.

Snapshot testing

jest-styled-components replaces opaque hashed class names with stable placeholders and includes actual CSS rules in snapshot output:

import { render } from '@testing-library/react';
import 'jest-styled-components';


const Button = styled.button`color: red;`;


test('matches snapshot', () => {
  const { container } = render(<Button />);
  expect(container.firstChild).toMatchSnapshot();
});


// Snapshot output:
// .c0 { color: red; }
// <button class="c0" />

Without the plugin, snapshots would show only class="sc-bdVTJa eFzKmA" — unstable hashes that change on unrelated modifications.

Stylelint

Lint your styled components with stylelint!

Installation

For stylelint v15+ (recommended)

Configuring stylelint (v15+) for the first time? Follow these steps:

You need:

npm install --save-dev \
  stylelint \
  stylelint-config-standard \
  postcss-styled-syntax

Add a .stylelintrc file to the root of your project:

{
  "extends": [
    "stylelint-config-standard"
  ],
  "customSyntax": "postcss-styled-syntax"
}

For stylelint v14 and below

Note

Deprecated: stylelint-processor-styled-components is archived and no longer maintained. Upgrade to stylelint v15+ with postcss-styled-syntax if possible.

You need:

Note

We recommend using Stylelint v9+ as this has added features that allow us to report correct line numbers on CSS syntax errors

npm install --save-dev \
  stylelint \
  stylelint-processor-styled-components \
  stylelint-config-styled-components \
  stylelint-config-recommended

Add a .stylelintrc file to the root of your project:

{
  "processors": [
    "stylelint-processor-styled-components"
  ],
  "extends": [
    "stylelint-config-recommended",
    "stylelint-config-styled-components"
  ]
}

Setup

You need to run stylelint. Add a lint:css script to your package.json which runs stylelint with a glob to all of your styled components:

{
  "scripts": {
    "lint:css":"stylelint './src/**/*.js'"
  }
}
Note

The processor ignores javascript files that don't contain any styled-components, so don't worry about being too broad as long as you restrict it to javascript (or TypeScript).

Now you can lint your CSS by running the script:

npm run lint:css
Note

Stylelint --fix option works with same rules on version 15+.

Webpack

If you want to lint on build, rather than as a separate command, you can use the stylelint-custom-processor-loader for webpack.

Legacy: stylelint-processor-styled-components specific sections

Note

The following sections (stylelint-config-styled-components, Usage with other libraries, and Interpolation tagging) apply only to the deprecated stylelint-processor-styled-components (stylelint v14 and below). If you are using the recommended postcss-styled-syntax setup with stylelint v15+, you can skip these sections.

stylelint-config-styled-components

When using this processor a couple of stylelint rules throw errors that cannot be prevented, like no-empty-source or no-missing-end-of-source-newline. There's also a couple rules which we need to enforce, like no-vendor-prefix rules. (In v6+, vendor prefixing is disabled by default; if you enable it via StyleSheetManager, you don't need to add prefixes manually.)

The stylelint-config-styled-components will automatically disable rules that cause conflicts.

Note

You can override rules defined in shared configs in your custom .stylelintrc.

Usage with other libraries

Some other libraries also implement the styled.x pattern with tagged template literals. This processor will lint the CSS in those tagged template literals too, as long as they use the styled keyword.

If you want to use the processor with another library but you also want to change the keyword (e.g. to write cool.div instead of styled.div) use the moduleName option:

import cool from 'other-library';


const Button = cool.button`
  color: blue;
`;
{
  "processors": [
    [
      "stylelint-processor-styled-components",
      {
        "moduleName": "other-library"
      }
    ]
  ]
}
Note

That double array is on purpose but only necessary if you set options, see the processors configuration docs.

Note

We only officially support styled-components, but the hope is that other libraries can also benefit from the processor.

Interpolation tagging (with stylelint-processor-styled-components)

Sometimes stylelint can throw an error (e.g. CssSyntaxError) even though nothing is wrong with your CSS. This is often due to an interpolation, more specifically the fact that the processor doesn't know what you're interpolating.

A simplified example:

const something = 'background';


const Button = styled.div`
  ${something}: papayawhip;
`;

When you have interpolations in your styles the processor can't know what they are, so it makes a good guess and replaces them with a syntactically equivalent placeholder value. Since stylelint is not a code flow analysis tool this doesn't cover all edge cases and the processor will get it wrong every now and then.

Interpolation tagging allows you to tell the processor what an interpolation is in case it guesses wrong; it can then replace the interpolation with a syntactically correct value based on your tag.

For example:

const something = 'background';


const Button = styled.div`
  // Tell the processor that "something" is a property
  ${/* sc-prop */ something}: papayawhip;
`;

Now the processor knows that the something interpolation is a property, and it can replace the interpolation with a property for linting.

To tag an interpolation add a comment at either the start or the end of the interpolation. (${/* sc-tag */ foo} or ${bar /* sc-tag */}) Tags start with sc- and, if specified, a tag overrides the processors guess about what the interpolation is.

Tags

The full list of supported tags:

  • sc-block
  • sc-selector
  • sc-declaration
  • sc-property
  • sc-value
Note

If you are in doubt of the vocabulary you can refer to this CSS vocabulary list with examples.

For example, when you interpolate another styled component, what you really interpolate is its unique selector. Since the processor doesn't know that, you can tell it to replace it with a selector when linting:

const Wrapper = styled.div`
  ${/* sc-selector */ Button} {
    color: red;
  }
`;

You can also use shorthand tags to avoid cluttering the code. For example:

const Wrapper = styled.div`
  ${/* sc-sel */ Button} {
    color: red;
  }
`;

sc-custom

sc-custom is meant to be used as a last resort escape hatch. Prefer the standard tags if possible.

On top of the above standard tags the processor also has the sc-custom tag to allow you to cover more unique and uncommon edge cases. With the sc-custom tag you can decide yourself what the placeholder value will be.

For example:

// Switch between left and right based on language settings passed through via the theme
const rtlSwitch = (props) => (props.theme.dir === 'rtl' ? 'left' : 'right');


const Button = styled.button`
  background: green;
  // Tell the processor to replace the interpolation with "left"
  // when linting
  margin-${/* sc-custom "left" */ rtlSwitch}: 12.5px;
`;

Syntax notes

Turning rules off from within your JS/CSS

Turn off rules with stylelint-disable comments (see the stylelint documentation for all allowed syntax) both inside and outside of the tagged template literals.

import React from 'react';
import styled from 'styled-components';


// Disable stylelint from within the tagged template literal
const Wrapper = styled.div`
  /* stylelint-disable */
  background-color: 123;
`;


// Or from the JavaScript around the tagged template literal
/* stylelint-disable */
const Wrapper = styled.div`
  background-color: 123;
`;

Template literal style and indentation

In order to have stylelint correctly apply indentation rules the processor needs to do a bit of opinionated preprocessing on the styles, which results in us only officially supporting one indentation style. (the supported style is the "default" one as shown in all the documentation)

The important thing is that you put the closing backtick on the base level of indentation as follows:

Right:

if (condition) {
  const Button = styled.button`
    color: red;
  `;
}

Wrong:

if (condition) {
  const Button = styled.button`
    color: red;
`
}
if (condition) {
  const Button = styled.button`
    color: red;`
}

It may be that other tagged template literal styles are coincidentally supported, but no issues will be handled regarding indentation unless the above style was used.

TypeScript Plugin

typescript-plugin-styled-components is a plugin for TypeScript that gives you a nicer debugging experience.

Note

⚠️ TypeScript does not allow to use any plugin or transformer directly from the command line compiler tsc. So the plugin only works with build toolchains such as webpack with one of TypeScript loaders. There's an open issue to bring plugins to tsc though if you want to upvote it!

Please refer to the project's GitHub repo for documentation.

Syntax Highlighting

Writing CSS in template literals requires editor support for syntax highlighting. Plugins are available for Visual Studio Code, Sublime Text, NeoVim, WebStorm, and more.

This is what it looks like when properly highlighted:

Syntax highlighted styled component

Sublime Text

A PR by @garetmckinley has been merged into babel-sublime but has not been released to Package Control. It is, however, available to install directly from GitHub as described in this issue.

Another option is Naomi by Alexandre Borela, a collection of syntax highlighting definitions for Sublime Text 3 which supports styled-components out-of-the-box.

Visual Studio Code

@gandm's language-babel has been ported to VSCode under the name Babel JavaScript by Michael McDermott. It provides the same all-in-one solution for Babel syntax highlighting with styled-components included.

If you would like to keep your current JavaScript syntax highlighting, you can use the vscode-styled-components extension to provide styled-components syntax highlighting inside your Javascript files. You can install it as usual from the Marketplace.

NeoVim

If you're using NeoVim with TreeSitter, you can add styled into your config's ensure_installed table:

require'nvim-treesitter.configs'.setup {
  ensure_installed = { ..., "styled" },
  highlight = {
    enable = true,
  },
}

WebStorm, IntelliJ IDEA, PhpStorm, PyCharm, and RubyMine

The webstorm-styled-components plugin adds code completion and highlighting for CSS properties and values in the template strings. And it also provides code completion and navigation for JavaScript symbols in the interpolations. You can install it from the IDE: go to Preferences | Plugins and search for Styled Components.

Other Editors

We could use your help to get syntax highlighting support to other editors! All these syntax highlighting were built by the Styled Components community so if you want to start working on syntax highlighting for your editor, we would love to see it.

Styled Theming

Note

The styled-theming package is no longer actively maintained. It may still work with current versions of styled-components, but consider using the built-in theming API directly for new projects.

Create themes for your styled components using styled-theming

Read more on the npm page

Install

Install the package:

npm install --save styled-theming

Example

import React from 'react'
import styled, { ThemeProvider } from 'styled-components'
import theme from 'styled-theming'


const boxBackgroundColor = theme('mode', {
  light: '#fff',
  dark: '#000',
})


const Box = styled.div`
  background-color: ${boxBackgroundColor};
`


export default function App() {
  return (
    <ThemeProvider theme={{ mode: 'light' }}>
      <Box>Hello World</Box>
    </ThemeProvider>
  )
}

API

<ThemeProvider>

See styled-components docs

<ThemeProvider> is part of styled-components, but is required for styled-theming.

import { ThemeProvider } from 'styled-components'

<ThemeProvider> accepts a single prop theme which you should pass an object with either strings or getter functions. For example:

<ThemeProvider theme={{ mode: "dark", size: "large" }}>
<ThemeProvider theme={{ mode: modes => modes.dark, size: sizes => sizes.large }}>

You should generally set up a <ThemeProvider> at the root of your app:

function App() {
  return (
    <ThemeProvider theme={...}>
      {/* rest of your app */}
    </ThemeProvider>
  );
}

theme(name, values)

Most of your theming will be done with this function.

name should match one of the keys in your <ThemeProvider> theme.

;<ThemeProvider theme={{ whatever: '...' }} />
theme("whatever", {...});

values should be an object where one of the keys will be selected by the value provided to <ThemeProvider> theme.

<ThemeProvider theme={{ mode: "light" }} />
<ThemeProvider theme={{ mode: "dark" }} />


theme("mode", {
  light: "...",
  dark: "...",
});

The values of this object can be any CSS value.

theme("mode", {
  light: "#fff",
  dark: "#000",
});


theme("font", {
  sansSerif: '"Helvetica Neue", Helvetica, Arial, sans-serif',
  serif: 'Georgia, Times, "Times New Roman", serif',
  monoSpaced: "Consolas, monaco, monospace",
});

These values can also be functions that return CSS values.

theme('mode', {
  light: props => props.theme.userProfileAccentColor.light,
  dark: props => props.theme.userProfileAccentColor.dark,
})

theme will create a function that you can use as a value in styled-component's styled function.

import styled from 'styled-components'
import theme from 'styled-theming'


const backgroundColor = theme('mode', {
  light: '#fff',
  dark: '#000',
})


const Box = styled.div`
  background-color: ${backgroundColor};
`

theme.variants(name, prop, themes)

It's often useful to create variants of the same component that are selected via an additional prop.

To make this easier with theming, styled-theming provides a theme.variants function.

import styled from "styled-components";
import theme from "styled-theming";


const backgroundColor = theme.variants("mode", "variant", {
  default: { light: "gray", dark: "darkgray" },
  primary: { light: "blue", dark: "darkblue" },
  success: { light: "green", dark: "darkgreen" },
  warning: { light: "orange", dark: "darkorange" },
});


const Button = styled.button`
  background-color: ${backgroundColor};
`;


<Button />
<Button variant="primary" />
<Button variant="success" />
<Button variant="warning" />