DEV Community

Cover image for Setting up React.js(CRA) with Tailwind CSS and CSS-IN-JS
Angel Martinez
Angel Martinez

Posted on • Updated on

Setting up React.js(CRA) with Tailwind CSS and CSS-IN-JS

I'll explain how install and configure Tailwind CSS / Emotion and twin.macro in a Single Project of React to improve the way we use styles in our projects.

Setting up our Project

The first step, is generate or create our React project in this case is using the create-react-app package, so we need to run the following command in the terminal or CMD:

npx create-react-app react-with-tw
Enter fullscreen mode Exit fullscreen mode

Once the project creation is finished, enter to the folder cd react-with-tw

Install Dependencies

Now, we need to install all of the dependencies that we needed, inside the project run the following command in the terminal:

npm i tailwindcss twin.macro @emotion/core @emotion/styled
Enter fullscreen mode Exit fullscreen mode
  • tailwindcss is the package of TailwindCSS with all the features and customization of Tailwind CSS.

  • @emotion/core and @emotion/styled they are libraries for writing a powerful CSS with JavaScript in our project.

  • twin.macro basically converts your Tailwind classes into CSS objects and shares them with @emotion to give you the power of writing with Styled Components.

So, once installed we can proceed to configure them and start using.

Configuration File of Tailwind CSS

Now, we start configure Tailwind CSS in our project, the first step is generate a configuration file, and then our tailwind.css file, so lets do it.

In the terminal, write the following command to generate a configuration file of tailwind.

npx tailwindcss init --full
Enter fullscreen mode Exit fullscreen mode

With the --full flag we tell tailwind that we want is the full configuration file.

The output of this is the tailwind.config.js with the following code:

// tailwind.config.js
module.exports = {
  purge: [],
  target: 'relaxed',
  prefix: '',
  important: false,
  separator: ':',
  theme: {
    screens: {
      sm: '640px',
      md: '768px',
      lg: '1024px',
      xl: '1280px',
    },
...
Enter fullscreen mode Exit fullscreen mode

In this file, you can customize all of the thing about tailwind (breakpoints, colors, margins and padding).

This file, is automatically generated in the root folder, but we need to move into the /src folder.

Configure our custom config location

In this step, we need to configure the route of our tailwind.config.js file, so, in the package.json we need to put the following code:

// package.json
"babelMacros": {
  "twin": {
    "config": "src/tailwind.config.js"
  }
},
Enter fullscreen mode Exit fullscreen mode

If you have another path, change the config line.

Import Tailwind CSS in our Project

Here we need to import the base.min.css file that TailwindCSS has available from its node_module package, in your index.js or your entry point file put the following code to import the tailwind styles:

import 'tailwindcss/dist/base.min.css';
Enter fullscreen mode Exit fullscreen mode

If you have a custom tailwind.css file for any reason, you can replace the base.min.css with your own file.

Using twin.macro

Now, we can use all of the features of tailwind / @emotion and twin.macro, here you can see some examples.

Pass props into a JSX elements

/** @jsx jsx */ import { jsx } from '@emotion/core'
import tw from 'twin.macro';

const MyComponent = () => {

    return (
        <h1 tw="text-blue-500 text-2xl" >Hello world</h1>
    )
}

export default MyComponent;
Enter fullscreen mode Exit fullscreen mode

Create Styled Componets

import tw from 'twin.macro';

// Styled Components
const MyHeading = tw.h1`text-blue-500 text-2xl`; 

const MyComponent = () => {

    return (
        <MyHeading>Hello World</MyHeading>
    )
}

export default MyComponent;
Enter fullscreen mode Exit fullscreen mode

Clone an Existing Styled Component

import tw from 'twin.macro';

// Styled Components
const MyButton = tw.button`border-2 px-4 py-2`
const MyPrimaryButton = tw(MyButton)`border-blue-500 bg-blue-500`; 

const MyComponent = () => {

    return (
        <MyPrimaryButton>My Button</MyPrimaryButton> 
    )
}

export default MyComponent;
Enter fullscreen mode Exit fullscreen mode

Pass props and Conditional Styles

import tw, { styled } from 'twin.macro';

// Styled Components
const MyButton = tw.button`border-2 px-4 py-2`
const MyPrimaryButton = tw(MyButton)`border-blue-500 bg-blue-500`; 
const MyPrimaryButtonCustomizable = styled(MyPrimaryButton)(({isUppercase}) => [
    tw`mx-2`,
    isUppercase && tw`uppercase`
]);

const MyComponent = () => {

    return (
        <MyPrimaryButtonCustomizable isUppercase>My Button</MyPrimaryButtonCustomizable> 
    )
}

export default MyComponent;
Enter fullscreen mode Exit fullscreen mode

Well, we have it, twin.macro within our project to take more advantage of using TailwindCSS. If you have anything to add or fix, feel free to let me know in the comments.

The repository with all ready to use: cra-template-tailwindcss-styled

Top comments (3)

Collapse
 
benrogerson profile image
Ben Rogerson

There are a few things you could adjust with this setup:

"Make a build of TailwindCSS" - you can remove that whole section.
There's actually no need to generate the Tailwind classes as the class conversions are all handled by twin.macro!
All you need to import is the base style file (import 'tailwindcss/dist/base.min.css';)

In the tailwind.config file, Twin only reads the theme and plugin values. The other values won't do anything with Twin.

Everything else is great! Thanks for writing this awesome article :)

Collapse
 
angelmtztrc profile image
Angel Martinez • Edited

Thank you very much for your advice. I already updated the post. I kept the configuration file of TailwindCSS because is more helpful if all we can see which things we can edit in TailwindCSS. By the way, I updated the GitHub repository and tomorrow the template for create-react-app will be available in NPM to use it.

Collapse
 
mitchstewart08 profile image
Mitchell Stewart

Great post, thanks!