Tailwind CSS in JS

Adding Tailwind to a Create React App with the help of styled-components and a babel-macro

Tl,dr: We can setup Tailwind in a Create React App, version 2+. Therefore we don’t even need to eject or manipulate any build task. Today, you can use a babel-macro and most CSS in JS solutions. Take a look at this demo React project

Tailwind is a utility css framework, which gives you specific, rememberable css classes to set, instead of writing plain css rules. It aims to help you build rich user interfaces fast. One can declare the needed utilities by editing a config JavaScipt file. Find out more in their docs.

Another solid approach to write your css in modern React components is CSS in JS. This term describes different set of tools allowing you to write CSS directly in your JavaScript files, colocating the styling to your components. One of the more popular CSS in JS frameworks in the React ecosytem is styled-components.

So, which approach to use? Why not both at the same time? That would give us the fast tailwind experience, while feeling more natural to the React component model. It also allows you to easily fall back to plain CSS via styled-components, if you need to.

Modern wind mills on a field. Metaphor for wind like in Tailwind.

Not a official logo, neither of Tailwind CSS nor React. But kinda windy. Photo by RawFilm on Unsplash.

Setting a React App with Tailwind up

To get started we want to use Create React App the one command solution to set up a modern React dev environment. The good news is, even if Create React App does not allow you to modify its build setup, we can integrate tailwind and styled-components without ejecting and therefore without leaving the official supported paths.

To get started, open a terminal and create a new app.

npx create-react-app cra-tailwindcss-in-js
cd cra-tailwindcss-in-js

We’ll need some additional dependecies, so go ahead and install them right away.

npm i -D tailwindcss tailwind.macro
npm i -S styled-components

Tailwind need a JavaScript configuration file to know which utilities to create. Luckily, it comes with a command to generate a good default setup.

./node_modules/.bin/tailwind init ./src/tailwind.js

You may have noticed that we generated this file in the ./src subfolder. This is where all of our source files live, and also Create React App complains, if we import from other locations. We installed tailwind.macro before. In order for that to pick up our configuration file, add a babel-plugin-macros.config.js in projects’ root folder.

// babel-plugin-macros.config.js
module.exports = {
  tailwind: {
    config: './src/tailwind.js',
  },
};

That’s it for the configuration. Start with npm run start.

Nice, but what did we get, how to use tailwind in our fancy new React App? Well, like so, with the help of our tw macro.

// App.js
import React, { Component } from 'react';
import styled from 'styled-components/macro';
import tw from 'tailwind.macro';

// use tailwind classes the styled way
const Header = styled.header`
  ${tw`bg-black min-h-screen flex flex-col items-center justify-center text-xl text-white`};
`;

class App extends Component {
  render() {
    // or inline via fancy css prop
    return (
      <div css={tw`text-center`}>
        <Header>
          <p css={tw`text-blue-light`}>
            Using <code>tailwind</code> and <code>styled-components</code>{' '}
            together.
          </p>
        </Header>
      </div>
    );
  }
}

export default App;

Beautiful, right? We can even use the fancy and new css prop, which is a quite direct way to style your components.

But, how does it work?

In its latest version, Create React App added support for babel-plugin-macros. That allows us to modify some part of our builds. Even luckier, there is a tailwind-macro, which we use here. That is what gives us the tw function thing we used in the code example. And there’s also a macro for styled-components, giving us style minification, a better debugging experience and the css prop.

I wrote about Tailwind and React before, but the setup described here has the significant benefit of only adding the used CSS rules to your build. The older article required you to set some task up outside your Create React App tasks.

As mentioned, an inspirational project is open sourced on GitHub, so see for yourself! For any question or other discussions, please reach out down there in the comments or on my twitter.

Published January 21, 2019

Comments, anyone?

READ THIS NEXT:
Revealing Prisma GraphQL's magic tricks

Prisma is a GraphQL API Layer. Trying it out with one of the available boilerplates gives you a ton of great features, almost feeling like magic. But is it? Let's have a look behind the tricks!