How one CSS-in-JS library cut 56 KB from my bundle
Tags: react, webperf, frontend
Published: 2020-05-10 09:29:41

---
title: "How one CSS-in-JS library cut 56 KB from my bundle"
published: true
description: "Styled-Components and Emotion are two popular CSS-in-JS libraries. This article introduces an alternative that comes with performance benefits."
tags: ["react","webperf","frontend"]
canonical_url: https://perfbeacon.com/blog/how-one-css-in-js-library-cut-56kb-from-bundle/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/mon4ro03bxupjbys1bno.jpg
---


Like many people working within the React ecosystem, I use a CSS in JS solution for implementing styles. 

The two CSS-in-JS libraries I've used most in my projects are [Emotion](https://emotion.sh/) and [Styled Components](https://styled-components.com/). They became quite popular as they let you define JSX components via an intuitive API:
```jsx
const Button = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0 1em;
  padding: 0.25em 1em;
`
``` 

## Performance overhead

These libraries have a great developer experience, but they do have **some** performance overhead.

On library size alone: 
- Styled Components adds [12.5kB (minified + gzipped)](https://bundlephobia.com/result?p=styled-components@5.1.0) 
- Emotion adds [4.8kB (minified + gzipped)](https://bundlephobia.com/result?p=@emotion/styled@10.0.27) via the `@emotion/styled` package, and an extra [6.5kB (minified + gzipped)](https://bundlephobia.com/result?p=@emotion/core@10.0.28) via the `@emotion/core` package

As well as the additional bundle size, these libraries generate your styles at runtime. In other words, your user's browser is the one doing the work to generate the CSS you declared via the amazing developer experience.

What if I told you it was possible to have both an amazing developer experience AND be performant?

## Introducing Compiled CSS-in-JS

[Compiled CSS in JS](https://compiledcssinjs.com/) (npm package: `@compiled/css-in-js`) does what it says on the box - it generates the styles you define at build time, so your user's browser has no extra work to perform to load your page properly.

On top of that, `@compiled/css-in-js` is only [964B (minified + gzipped)](https://bundlephobia.com/result?p=@compiled/css-in-js@0.3.2), and results in around 300B being added to your bundle thanks to tree-shaking.

Compiled CSS in JS supports both the `styled` component and the `css` prop, so adopting it is as simple as installing a couple of packages, removing the old packages, and a quick search and replace.

I didn't have particularly complicated `styled` components, so migration was seamless. There are some cases where you'd have to [re-write your code](https://compiledcssinjs.com/docs/migrating#generating-css-at-runtime), but I haven't had to.


[Compiled CSS in JS](https://compiledcssinjs.com/) is still pretty early in its development, so if you don't consider yourself an early adopter, you might want to wait until it's more mature/widely adopted. 

Definitely a package you'd want to watch though!


## How to use Compiled CSS-in-JS

To get started with Compiled CSS-in-JS, we head over to the [docs](https://compiledcssinjs.com/docs/). 

I wasn't using TypeScript on the personal projects I added Compiled CSS-in-JS to, but there are instructions in the docs to help TypeScript users too.

- Install the library
```
npm install @compiled/css-in-js
or
yarn add @compiled/css-in-js
```
- Install the Babel plugin
```
npm install @compiled/babel-plugin-css-in-js
or 
yarn add @compiled/babel-plugin-css-in-js
```

- Search and replace

    Depending on the CSS-in-JS library you use, your search and replace could be one of the following:
    - `import styled from 'styled-components';` for `import { styled } from '@compiled/css-in-js';`
    -  `import styled from '@emotion/styled';` for `import { styled } from '@compiled/css-in-js';`


Each time I swapped to Compiled CSS in JS my bundle size dropped considerably, and First Contentful Paint (FCP) dropped by at least 100ms.

If you'd like more tips on how to improve your frontend's web performance, you can [follow me on Twitter](https://twitter.com/RozenMD) or [subscribe to my newsletter](https://maxrozen.com/newsletter/) as I regularly post articles there.