by Francesco Agnoletto

How to add styled-components to a React application

Using emotionjs to take full advantage of CSS-in-JS

Photo by David Pisnoy on Unsplash

I’ve talked about the advantages of CSS-in-JS and styled-components in a previous article you can find here.
A few days ago I had to set up it from scratch again and hated doing it. It does require quite a few actions to leverage the full advantages it can offer so let’s see all the steps required.

Install emotion

I prefer emotionjs between the CSS-in-JS libraries. It works very well with TypeScript and has an easy syntax.

$ npm i @emotion/core @emotion/styled will add the basic packages. @emotion/core is required, @emotion/styled only if you want styled-components. I favor the latter but sometimes use core for either some small styling with css or keyframes.

The vscode styled-components extension for syntax highlight and IntelliSense is a must.

Setting up .babelrc

Babel requires a plugin to parse emotion.
The default setup requires installing babel-plugin-emotion but it does not include the css prop. @emotion/babel-preset-css-prop does and includes the default plugin.

// the css prop
const Button: React.FC<IProps> = props => (
  <a
    css={{
      color: 'hotpink',
      '&:hover': {
        color: 'darkorchid'
      }
    }}
    {...props}
  />
)

$ npm i -D @emotion/babel-preset-css-prop will install it.
The emotion plugin needs to appear after @babel/preset-react and @babel/preset-typescript in the list of plugins in case you are using them (you should!).

// recommended .babelrc config for emotionjs
{
  "env": {
    "production": {
      "presets": [
        "@babel/react",
        "@babel/typescript",
        "@emotion/babel-preset-css-prop"
      ]
    },
    "development": {
      "presets": [
        "@babel/react",
        "@babel/typescript",
        ["@emotion/babel-preset-css-prop", { "sourceMap": true }]
      ]
    }
  }
}

Linting with style

Stylelint adds rules and checks for styled-components libraries. Since emotionjs is based on styled-components, the linting is fully compatible. It is also enabled by default.
$ npm i -D stylelint stylelint-config-standard
You can set up custom rules as well, declaration-empty-line-before is for prettier compatibility.

// .stylelintrc
{
  "extends": [
    "stylelint-config-standard"
  ],
  "rules": {
    "declaration-empty-line-before": null,
  }
}

Install the vscode extension to enable default detection on vscode.

Closing thoughts

Setting up new libraries can be a chore, especially when the documentation is spread in different places.
The advantages of using styled-components outweigh the initial set up chore. But it doesn’t mean it has to be a time-consuming activity.