Emotion in React
Tags: react, javascript, css
Published: 2020-07-29 13:11:47

---
title: Emotion in React
published: true
date: 2020-07-22 16:00:19 UTC
tags: react,javascript,css
canonical_url: https://blog.logrocket.com/emotion-in-react/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/ehpey5987sl60ihdtw9z.png
---
**Written by [Leonardo Maldonado](https://blog.logrocket.com/author/leonardomaldonado/)**✏️

CSS-in-JS is a commonly used concept when solving CSS problems and styling modern applications. When starting a new project, it can be tricky to decide on which CSS-in-JS library to use.

A problem we often run into is that most of the time, we’re building applications that will be used by a lot of people. An application can quickly scale to millions of users depending on its success, and choosing the wrong CSS-in-JS library for your project could end up costing a lot in the future.

The ecosystem of CSS-in-JS libraries is getting better every day, libraries are getting more mature and robust, new features and support are being added, and problems that were once really painful to solve are becoming easier.

Emotion is one of these CSS-in-JS libraries that is more mature and consistent, [due to the work of the whole community involved](https://github.com/emotion-js/emotion/graphs/contributors). In this post, we will learn more about Emotion, and see the features and advantages that it can bring to our applications.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## Emotion

[Emotion](https://emotion.sh/docs/introduction) is a high performance, flexible, and performant CSS-in-JS library. Emotion helps us to style our application in a faster way, with a decent and consistent CSS composition.

Here are some of the features of Emotion.

## Performance

Emotion is a really performant library because it uses a philosophy that comes from a library called [glam](https://github.com/threepointone/glam). The idea is to have the best runtime performance without compromising the runtime cost.

The result is a super fast and small library that is really great for prototyping and design systems. With Emotion, objects can be used everywhere and it is easily composable with arrays.

## Framework agnostic

Emotion is a framework-agnostic library, which means that it can be used in a different range of frameworks and libraries. You’re able to use it everywhere you want, with the same powerful API and features. This is not something exclusive to Emotion, we have some other CSS-in-JS libraries that are framework agnostic. However, the idea to reuse Emotion in different projects is fascinating because, for example, you could build a whole design system with support for web and mobile just using Emotion.

Emotion has a package called `@emotion/native` that’s for React Native itself, so there’s no need for the developer to use Emotion on the web and use another CSS-in-JS library on mobile.

To start to style your React Native apps using Emotion, all you have to do is install the packages:

```jsx
yarn add @emotion/core @emotion/native
```

## No additional set up

Emotion requires no additional setup to get started. It has support for nested selectors, media queries, and auto vendor-prefixing. It’s really composable and great for prototyping, you can use just the `CSS` function and the `cx` to compose everything in your application.

To get started with Emotion, all you have to do is install the package:

```jsx
yarn add emotion
```

Now you are able to create your first styled component using Emotion:

```jsx
import { css, cx } from 'emotion'

render(
  <div
    className={css`
      padding: 10px;
      background-color: red;
      font-size: 16px;
      border-radius: 6px;
    `}
  >
    Emotion CSS-in-JS
  </div>
)
```

Emotion is still different in some ways from other famous libraries such as styled-components and Radium. Let’s understand some of the differences that separate Emotion from other CSS-in-JS libraries and what makes it so performant and flexible.

## Styling

There are different Emotion packages, that were created for different use cases. When using Emotion in an application, you need to know the differences between these packages so you won’t be installing more than you need and increasing your bundle size.

The `emotion` package is framework agnostic, so if you decide to use Emotion in other applications that are not using React, this is the right package for you:

```jsx
yarn add emotion
```

The `@emotion/core` package requires React, so this is the right package for you if you’re using Emotion in a React application:

```jsx
yarn add @emotion/core
```

## CSS prop

The first difference that we notice with Emotion compared to the other famous CSS-in-JS libraries is styling. The primary way to style components using Emotion is to use the `CSS` prop.

The `CSS` prop allows us to apply styles direct to our component or element without having to create a styled component. There are two ways to use the `CSS` prop correctly.

First, if you’re working in a project that you are able to configure a custom babel config, you have to use the `@emotion/babel-preset-css-prop` in your `.babelrc`:

```jsx
{
 "presets": ["@emotion/babel-preset-css-prop"]
}
```

In case you’re using some boilerplate or starter such as [create-react-app](https://github.com/facebook/create-react-app), you might not be able to configure a custom babel config, you will need to use the second option, the JSX Pragma.

All you have to do is use the JSX Pragma on the top of your file that’s using the CSS prop, and import the `jsx` from `@emotion/core`, like this:

```jsx
/** @jsx jsx */
import { jsx } from '@emotion/core'
```

JSX Pragma is basically a code that tells the babel plugin to use the `jsx` function instead of `React.createElement`.

Now, you can use the `CSS` prop in any element of your file:

```jsx
/** @jsx jsx */
import { jsx } from '@emotion/core'
import React from "react";
const Header = () => {
  return (
    <header>
      <h3 css={{ color: 'lightgreen'}}>Hello World!</h3>
    </header>
  )
};
```

A nice feature of the `CSS` prop is that we can have access to the theme by default, by using a function that accepts the theme as the `CSS` prop:

```jsx
/** @jsx jsx */
import { jsx } from '@emotion/core'
import React from "react";
const Header = () => {
  return (
   <header>
     <h3 css={theme => ({ color: theme.color.primary}) }>Hello World!</h3>
   </header>
  )
};
```

## Style API

A lot of people are using styled-components nowadays, another famous CSS-in-JS library. One of the features that they might miss is the `styled.div` style API, that’s why Emotion has a package called `@emotion/styled`.

To use this style API, all we have to do is install the `@emotion/styled` package using the following command:

```jsx
yarn add @emotion/styled
```

And now we can use the style API combined with template literals to create styles very easily:

```jsx
import styled from '@emotion/styled';

const Button = styled.button`
  width: 100px;
  height: 40px;
  background-color: black;
  color: white;
`;
```

## Theming

Emotion also has support for theming, to work with it all we need to do is install the `emotion-theming` package:

```jsx
yarn add emotion-theming
```

The `emotion-theming` package provides the `ThemeProvider`, we should add this provider on the top level of our application and then we can have access to our theme in a styled component using the `props.theme`:

```jsx
import { ThemeProvider } from 'emotion-theming';

const theme = {
  colors: {
    primary: 'black',
    secondary: 'blue'
  },
  breakpoints: {
    sm: 380,
    md: 720,
  }
}

const App = () => {
  return (
    <ThemeProvider theme={theme}>
      ...
    </ThemeProvider>
  )
}
```

## Media queries

Working with media queries is simple using Emotion. For example, let’s imagine that we have an array of breakpoints:

```jsx
const breakpoints = [576, 768, 992, 1200];
```

We can just create a helper function to return the breakpoint that we want, like this:

```jsx
const mq = (n) => `@media (min-width: ${breakpoints[n]}px)`;
```

Now, inside our styled-components, we simply use our `mq` helper function and pass the media query that we want:

```jsx
 const Text = styled.h3`
  font-size: 16px;
  color: black;
  font-family: Inter;
  ${mq(1)} {
    color: green;
  }
  ${mq(2)} {
    color: hotpink;
  }
`;
```

## SSR by default

Server-side rendering is a popular technique and works out of the box with Emotion if you’re using the `@emotion/core` and the `@emotion/styled` packages.

The default approach is to use the `renderToString` from React which will insert a `<style>` tag above your element:

```jsx
import { renderToString } from 'react-dom/server'
import App from './App'

let html = renderToString(<App />)
```

The advanced approach is just in case you need to work with `nth child` or similar selectors, since the default approach is not the best for it. It requires a few more lines of code, but it works fine.

In your server, put the following code:

```jsx
import { CacheProvider } from '@emotion/core'
import { renderToString } from 'react-dom/server'
import createEmotionServer from 'create-emotion-server'
import createCache from '@emotion/cache'

const cache = createCache()
const { extractCritical } = createEmotionServer(cache)

let element = (
  <CacheProvider value={cache}>
    <App />
  </CacheProvider>
)

let { html, css, ids } = extractCritical(renderToString(element))

res
  .status(200)
  .header('Content-Type', 'text/html')
  .send(`<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>My site</title>
    <style data-emotion-css="${ids.join(' ')}">${css}</style>
</head>
<body>
    <div id="root">${html}</div>

    <script src="./bundle.js"></script>
</body>
</html>`);
```

Now, on the client-side, all you have to do is the following:

```jsx
const cache = createCache();

ReactDOM.hydrate(
  <CacheProvider value={cache}>
    <App />
  </CacheProvider>,
  document.getElementById('root')
);
```

## Should I use Emotion?

Emotion is a really performant and consistent CSS-in-JS library, in comparison with other libraries like styled-components. There’s a lot of content and comparisons between those two libraries, saying that [Emotion is 25x](https://medium.com/@tkh44/emotion-ad1c45c6d28b) faster than styled-components, etc. Even with the release of styled-components v5 last year, Emotion still has a little advantage over styled-components because it has a smaller bundle size and faster runtime. Aside from performance and runtime, both libraries have [almost the same functionalities and features](https://spectrum.chat/styled-components/general/emotion-vs-styled-components~706ff9c8-f06d-4433-a42c-cc158d385089).

So, should you use Emotion? There’s not an exact answer to this question, because it really depends on a lot of factors.

If it is your first time using a CSS-in-JS library you may want to start with styled-components. For a better understanding of CSS-in-JS in general, styled-components will work better for you and help to understand the principle concepts of CSS-in-JS and how it can work in real projects. The amount of content available by the community is huge and you can learn about CSS-in-JS really fast.

Have you used a CSS-in-JS library before and are looking for a smaller and faster library? I would go with Emotion. If you’re used to using CSS-in-JS libraries in your projects, you know exactly how and when to use it. Emotion can really help you to get to the next level and build more performative and scalable applications using CSS-in-JS.

## Conclusion

In this article, we learned more about Emotion, a powerful and performant CSS-in-JS library that has a lot of nice features. We learned about the core of Emotion, we used the `CSS` prop, and learned about theming.

* * * 
## [LogRocket:](logrocket.com/devto) Full visibility into production React apps 

Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, [try LogRocket.](https://www2.logrocket.com/react-performance-monitoring)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/eq752g8qhbffxt3hp9t4.png)

[LogRocket](https://logrocket.com/devto) is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — [start monitoring for free.](https://www2.logrocket.com/react-performance-monitoring)
* * *

The post [Emotion in React](https://blog.logrocket.com/emotion-in-react/) appeared first on [LogRocket Blog](https://blog.logrocket.com).