Setup Tailwind CSS in a React project configured from scratch with Webpack | a step-by-step guide
Tags: react, tailwindcss, webpack, javascript
Published: 2022-05-30 17:53:45

Tailwind CSS is a utility first CSS framework that allows developers to design custom web components without switching to a CSS file. In this guide I will walk you step-by-step through the process of setting up Tailwind CSS in a React project configured from scratch (without using `create-react-app`). We will install and configure Tailwind CSS and PostCSS, integrate them with CSS and Webpack and finally add Tailwind Styles in our React codebase. (much fun)  

**Attention!**
This article is a fourth part in the series of setting up a React environment from scratch. Throughout this series we already set a React project from scratch, installed ESLint, Prettier and husky, configured the testing environment with Jest and React Testing Library and In this part we will base on that progress and add Tailwind CSS for styling.

You can find the starting code from this [GitHub repo](https://github.com/Yvad60/blog-code-references/tree/setup-jest-and-react-testing-library)

**Prerequisites**
- I expect that you have a React project configured from scratch. for reference you can start from the Repo provided above, but you can still follow along if you need this article for any other reasons

- VS code and Node installed on your machine.

let's have an overview of the tools we will be using.

**Why Tailwind CSS?**
Tailwind CSS is self-described as a utility first CSS framework. Rather than focusing on the functionality of the item being styled, Tailwind is centered around how it should be displayed. With
> Rapidly build modern websites without ever leaving your HTML.

With Tailwind you can style directly from your `html` or `jsx` using Tailwind CSS predefined classes to enable you write CSS in a more elegant and faster way. This doesn't mean you should always use Tailwind as it can be an overkill for small projects and requires a decent understanding of CSS. Learn more about Tailwind CSS [HERE](https://tailwindcss.com/docs).

**PostCSS**
PostCSS is a tool for transforming styles with JavaScript plugins. and these plugins can improve your styles in many different ways. for instance the way we have [ESLint](https://eslint.org/) for JavaScript PostCSS allows you to use plugins that can detect errors in your CSS code, or use next generation CSS syntax (kinda like Babel for CSS) and much more. Tailwind CSS is one of these plugins therefore to use Tailwind we need PostCSS installed.
Learn more about PostCSS [HERE](https://github.com/postcss/postcss)

We will come back to these tools in more details later, for now let's get started. 

Follow the following steps

**1. Installing Tailwind dependencies**
Run the following command to Install Tailwind CSS (as a dev dependencies).

```js
npm install tailwindcss autoprefixer --save-dev

// using yarn

yarn add tailwindcss autoprefixer --dev
```
- `tailwindcss`: is a core package that installs Tailwind CSS
- `autoprefixer`: It's a PostCSS plugin that Tailwind CSS uses to automatically adds [vendor prefixes](https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix) to write styles supported by all browsers

**2. Configuring Tailwind CSS**
in the root folder create a file named `tailwind.config.cjs` which will hold your configurations and customizations for Tailwind, 
we named it with a `.cjs` extension because we we will be using the`require` syntax in ES module

in the `tailwind.config.cjs`add the following code

```js
module.exports = {
	content: ['./src/**/*.{js,jsx}', './public/index.html'],
	theme: {
		extend: {
			colors: {
				primary: '#1B73E8',
			},
		},
	},
	plugins: [],
};

``` 
What does the code mean? 
- We are exporting this configurations using `module.exports`

- The `content` field is very important as it specifies file types that we will add Tailwind code in. In our example we are telling Tailwind to look into all files in the `src` folder with `.js`and `jsx` extensions and the `index.html` in the public folder. 

- In the `theme` folder we will put our customizations by extending default configurations. in our example we are creating a variable of a color called `primary` to the color code `'#1B73E8'`, so anytime we mention `primary` as a color Tailwind CSS will insert it's value. basically you can define your styles accordingly

- The `plugins` field is where we put our plugins that we want to use with Tailwind in this example we are not using plugins so the array is empty

Note that there more configurations and you can customize it as you want. Learn more about tailwind configurations [HERE](https://tailwindcss.com/docs/configuration)

**3. Install PostCSS dependecies**
Run the following command to Install PostCSS (as a dev dependency).

```js
npm install postcss --save-dev

// using yarn

yarn add postcss  --dev
```

**4. Configuring PostCSS**
in the root folder create a file named `postcss.config.cjs` which will hold your configurations for PostCSS, and add the following code

```js
const tailwindcss = require('tailwindcss');
const autoprefixer = require('autoprefixer');

module.exports = {
	plugins: [tailwindcss('./tailwind.config.cjs'), autoprefixer],
};
``` 
What does the code mean?

- We are importing Tailwind css  and autoprefixer packages we installed earlier using `require` you can use import if you are using ES modules
- in the configurations exports we are mentioning plugins that PostCSS will use while going through our CSS files. in our case we are specifying tailwind and autoprefixer. 
for tailwind we specified the path for our tailwind configuration file (`tailwind.config.cjs`). Learn more about PostCSS configurations [HERE](https://github.com/postcss/postcss-load-config#postcssrcjs-or-postcssconfigjs)

**5. Inject Tailwind in the CSS file**
We Installed and configured Tailwind CSS and PostCSS in our codebase but how do we add Tailwind CSS in our React components. as mentioned above, Tailwind CSS uses predefined classes that corresponds to actual CSS properties. technically we still need to have css files even if we are not directly writing CSS.

- in the src folder where we have `App.jsx` (created in previous articles) create a file named `app.css` which will be our main CSS file.
- in the `app.css` add the following code 
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
this will inject tailwind styles in our css file using tailwind directives. this is like importing Tailwind styles to be recognized as real CSS syntax. learn more about Tailwind directives [HERE](https://tailwindcss.com/docs/functions-and-directives)

- Finally import that CSS file in the entry file for your React project. in this example I will put it in the `App.jsx` file.

your `app.jsx` should look like this
```js
import React from 'react';
import './app.css'; //added line

function App() {
	return <h1>Hello world! I am using React</h1>;
}

export default App;
```
**6. Support CSS with Webpack**
In the [first article](https://dev.to/yvad60/how-to-create-a-react-app-without-using-create-react-app-a-step-by-step-guide-30nl) configured our react project with Webpack for bundling all files into a single javascript file that is served with our `index.html`. 
The thing with Webpack is that it doesn't support files out of the box every time we add new types of files, we need to make Webpack recognize them using it's loaders and we did the same thing for `.js` and `jsx` files in the first article.

in this article we just added a `.css` file in our codebase therefore we need to install loaders for CSS so that Webpack can recognize it 

Run the following command to Install Webpack CSS loaders  (as a dev dependencies).
```js
npm install style-loader css-loader postcss-loader

// using Yarn

yarn add style-loader css-loader postcss-loader --dev
```
-`style-loader`: used by webpack to inject CSS into the DOM.
-`css-loader`: used by webpack to interprets and resolve imports in CSS
-`postcss-loader`: used by webpack to process PostCSS as we installed PostCSS earlier.

After installing these loader we need to add them in our `webpack.config.js` by adding a new rule in the modules object 

```js
{
  test: /\.css$/i,
  use: ['style-loader', 'css-loader', 'postcss-loader'],
},
```
- Here we are telling Webpack that when it encounter a file with `.css` extension it should use the loaders we installed to bundle them.

finally your full webpack.config.js should look like the following

```js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
	entry: 'index.jsx',
	mode: 'development',
	output: {
		path: path.resolve(__dirname, './dist'),
		filename: 'index_bundle.js',
	},
	target: 'web',
	devServer: {
		port: '5000',
		static: {
			directory: path.join(__dirname, 'public'),
		},
		open: true,
		hot: true,
		liveReload: true,
	},
	resolve: {
		extensions: ['.js', '.jsx', '.json'],
	},
	module: {
		rules: [
			{
				test: /\.(js|jsx)$/,
				exclude: /node_modules/,
				use: 'babel-loader',
			},
			{
				test: /\.css$/i,
				use: ['style-loader', 'css-loader', 'postcss-loader'],
			},
		],
	},
	plugins: [
		new HtmlWebpackPlugin({
			template: path.join(__dirname, 'public', 'index.html'),
		}),
	],
};

```

**7. Style your React components with Tailwind**
After these configurations you should be able to write tailwind code in any of your React components with no issues.
in the `app.jsx` add the following code

```js
import React from 'react';
import './app.css';

function App() {
	return <h1 className="text-primary text-4xl font-bold">Hello world! I am using React</h1>;
}

export default App;

```
we just added tailwind class to change our text the `primary` color we configured in `tailwind.config.cjs`, increase font size made text bold

after running the app with `npm start` the page should look like the following

![tailwind with react](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3z3249r6o3bhkae3k34g.png)

There you have it! that's how you configure Tailwind CSS in a react project configured from scratch with Webpack. you can find code for this article on this [GitHub Repo](https://github.com/Yvad60/blog-code-references/tree/setup-tailwind-css)

**What about tests?**
Currently if you try to run tests (`npm test`) they will fail as imported a CSS file and by default Jest doesn't understand CSS files therefore we will need to mock them and this will be the topic for the next article...