Migrating from Styled Components to Emotion

Migrating from Styled Components to Emotion

Tags
Bundling
Emotion
ES6
JavaScript
Migration
React.js
Styled-Components
Published
August 7, 2021
I recently migrated a fairly large project from using Styled Components to Emotion. For this guide, I will focus only on the how, and not the why. Styled Components and Emotion are both capable libraries with their own quirks that you can delve into on your own. I do really love their ability to simplify styling of react components.

Getting started

Firstly, you will need to install Emotion. For my examples I’ll be using yarn.
yarn add @emotion/styled @emotion/react
If you’re using babel, you’ll need to install the Emotion plugin as well.

A simple find and replace

In a lot of projects using Styled Components, you will likely have a lot of code that is similar to the following:
import styled from 'styled-components'; const Container = styled.div` padding: 5px; `; export function App({ children }) { return <Container>{children}</Container>; }
The APIs for Emotion and Styled Components for the styled export are very similar, and in most cases 100% compatible. So we can use the following find and replace to handle (hopefully) the majority of cases.
pt "import styled from 'styled-components'" -l | xargs sed -e "s:import styled from 'styled-components':import styled from '@emotion/styled':g" -i
Let me unpack that to explain what’s going on. First we want to find all the files that import styled from Styled Components. I’m using The Platinum Searcher, but you can use ag or rg if you want. The concept is the same. It will list all the files that match the given string.
pt "import styled from 'styled-components'" -l
We then pipe that into xargs which will run a command for each line that is piped into it based on its arguments. The command we wish to run for each file is sed, which will do the find and replace.
sed -e "s:import styled from 'styled-components':import styled from '@emotion/styled':g" -i
The -e argument is the pattern we wish to apply, which is a find and replace. From left to right you can read the pattern as: find A, then replace with B, for every instance of A. The -i argument instructs sed to do the replacement in-place rather than outputting to STDOUT.
Alternatively, if your IDE has a find and replace function, you can use that. I just like using the terminal.

Things that require manual migration

attrs()

I had a few instances of components that used the attrs() method to set attributes on the rendered component.

Before

const NotAButton = styled.div.attrs({ role: 'button', })` cursor: pointer `;
Emotion does not have this method on a Styled Component instance, so we need to replace it. The recommended way to do this is via defaultProps.

After

const NotAButton = styled.div` cursor: pointer; `; NotAButton.defaultProps = { role: 'button' };

Alternatively

The other way would be to use @emotion/react instead. Note here I’m making role a changeable property whereas in the initial implementation it was locked.
/** @jsx jsx */ \ import { jsx, css } from '@emotion/react'; const styles = css` cursor: pointer; ` function NotAButton({ role = 'button', ...props}) { return <div css={styles} role={role} {...props} />; }

createGlobalStyle

If you’re using createGlobalStyle, Emotion has a very similar pattern using Global and css from @emotion/react.

Before

import { createGlobalStyle } from 'styled-components'; const BodyColor = createGlobalStyle` background-color: red; `; export function App({ children }) { return ( <> <BodyColor /> {children} </> ); }

After

import { Global, css } from '@emotion/react'; const bodyColor = css` background-color: red; `; export function App({ children }) { return ( <> <Global styles={bodyColor} /> {children} </> ); }
Finally, do a search for styled-components in your project, you will find any remaining files that need to be updated to use Emotion. You should be able to follow the above steps for the rest of your project.

Cleanup

If you’re not using Styled Components at all anymore, you should remove it from your project to reduce your bundle size and complexity.
yarn remove styled-components
Again, if you’re using babel, you will need to remove the Styled Components plugin. After all is said and done you should have successfully migrated to Emotion! If you ran into any situations that I didn’t cover, let me know.
Happy coding!