I really like styled components and CSS in JS in general, but this has quickly overtaken as my favourite way to do styling in React. It took a little while to figure out the configuration so I'm going to share that here.
Link if you just want to see the working starter
The combination that works to make this seamless is as follows:
- Create React App
- TailwindCSS
- postcss-nested Use SASS style nested CSS rules.
- craco (Create-React-App-Configuration-Override) Allow us to use PostCSS to compile tailwind and the other plugins with webpack without the need for ejecting.
Getting set up
Using Create React App is very well documented. We'll start a new project and install our dev dependencies.
npx create-react-app cra-postcss-tailwind
cd cra-postcss-tailwind
yarn add -D @craco/craco autoprefixer postcss-nested tailwindcss
Setting up the basic webpack config
To allow us to customise the Create React App webpack config we'll be using Craco.
Create a tailwind.config.js
file in the root of the project for whatever customisations you like. This is also where we set up the production purge to get rid of unused utilities and keep file size down.
module.exports = {
purge: ["./src/**/*.html", "./src/**/*.jsx", "./src/**/*.js"],
theme: {
extend: {
screens: {
xs: { max: "400px" },
},
},
},
};
And create a craco.config.js
file to set up the postcss plugins:
module.exports = {
style: {
postcss: {
plugins: [
require("tailwindcss")("./tailwind.config.js"),
],
},
},
};
Now let's change the scripts inside package.json
to use craco
instead of react-scripts
. This is what allows us to bypass the restrictions with Create React App without ejecting.
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
},
Finally, let's set up the global stylesheet. Adding to the start of src/index.css
:
@tailwind base;
@tailwind components;
@tailwind utilities;
That's it for the basics, you should now be able to use tailwind in your markup with all the benefits of CRA with impunity. Let's run the project with yarn start
and add a utility class to test it out:
Nice.
Composition and modules
This setup comes with all the benefits of a normal CRA + PostCSS setup, which means we can compose classes inside CSS modules alongside regular CSS like this:
/* App.css */
.App {
width: 100vw;
height: 100vh;
@apply bg-green-500;
}
And with the inclusion of the postcss-nested
plugin we can have SASS style nesting as well:
// craco.config.js
require("tailwindcss")("./tailwind.config.js"),
require("postcss-nested"),
/* App.css */
.App {
width: 100vw;
height: 100vh;
@apply bg-green-500 flex items-center justify-center;
&-inner {
@apply bg-gray-900 text-white p-4;
}
}
// App.js
return (
<div className="App">
<div className="App-inner border border-white">Success!</div>
</div>
)
Resulting in this:
And that's it. This is definitely my new favourite way to do styling in React. Enjoy.
Top comments (6)
Failed to compile
./src/index.css (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-4-1!./node_modules/react-scripts/node_modules/postcss-loader/src??postcss!./src/index.css)
Error: PostCSS plugin tailwindcss requires PostCSS 8.
Migration guide for end-users:
github.com/postcss/postcss/wiki/Po...
Currently Create React App does not support PostCSS 8.
If you still want to use Tailwind with CRA, you'll need to use their compatibility branch for PostCSS 7. You can find instructions for that in the Tailwind installation docs.
Tailwind >v2.0 requires PostCSS 8. You should just be able to run
yarn add -D postcss
and have it working.This is not working for me either. Followed all steps. Below are my packages.
"@craco/craco": "^6.0.0",
"autoprefixer": "^10.2.1",
"postcss": "^8.2.3",
"postcss-cli": "^8.3.1",
"postcss-nested": "^5.0.3",
"tailwindcss": "^2.0.2"
Great!
I am using react-app-rewired and its works with:
module.exports = {
webpack: (config) => {
// Override config of webpack CRA
const overrideConfig = override(
addPostcssPlugins([
require('tailwindcss')('./tailwind.config.js'),
require('autoprefixer'),
]),
addWebpackAlias(nxPathAlias),
)(config);
return config;
},
};
Hey mate, what is nxPathAlias here?