Installing Tailwind CSS in a React project created with Vite is straightforward, but there's one common issue that trips up many developers. This guide will walk you through the entire process, including how to fix the ES module configuration error.
What You'll Learn
- How to create a new React project with Vite
- Installing Tailwind CSS and its dependencies
- Configuring Tailwind for your project
- Fixing the common ES module error
- Testing your setup
Prerequisites
- Node.js installed on your computer
- Basic knowledge of React
- Command line/terminal access
Step 1: Create a New React Project
First, create a new React project using Vite:
npm create vite@latest my-react-app
When prompted:
- Select React as the framework
- Choose JavaScript (or TypeScript if you prefer)
Navigate to your project directory:
cd my-react-app
Install the project dependencies:
npm install
Step 2: Install Tailwind CSS
Install Tailwind CSS and its peer dependencies:
npm install -D tailwindcss@^3.4.0 postcss autoprefixer
Step 3: Generate Tailwind Configuration Files
Create the Tailwind and PostCSS configuration files:
npx tailwindcss init -p
This command creates two files:
tailwind.config.js
postcss.config.js
Step 4: The ES Module Problem
If you try to run npm run dev
now, you'll likely encounter this error:
Failed to load PostCSS config: [ReferenceError] module is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension and
'package.json' contains "type": "module".
Why does this happen?
- Vite projects use
"type": "module"
inpackage.json
- This makes all
.js
files ES modules - But the generated config files use CommonJS syntax (
module.exports
) - This creates a conflict!
Step 5: Fix the Configuration Files
The solution is to rename the config files to use the .cjs
extension:
Rename the files:
- Rename
postcss.config.js
topostcss.config.cjs
- Rename
tailwind.config.js
totailwind.config.cjs
Verify the content:
postcss.config.cjs:
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
tailwind.config.cjs:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
Step 6: Add Tailwind Directives to CSS
Open src/index.css
and replace its contents with:
@tailwind base;
@tailwind components;
@tailwind utilities;
Step 7: Import CSS in Your App
Make sure your src/main.jsx
file imports the CSS:
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css' // This line is crucial!
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
Step 8: Test Your Setup
Replace the contents of src/App.jsx
with this test component:
function App() {
return (
<div className="min-h-screen bg-gradient-to-r from-blue-400 to-purple-500 flex items-center justify-center">
<div className="bg-white rounded-lg shadow-xl p-8 max-w-md">
<h1 className="text-3xl font-bold text-gray-800 mb-4">
π Tailwind CSS is Working!
</h1>
<p className="text-gray-600 mb-6">
Your React + Tailwind setup is complete and ready to use.
</p>
<button className="w-full bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded transition-colors">
Get Started
</button>
</div>
</div>
)
}
export default App
Step 9: Start Your Development Server
Run your development server:
npm run dev
Visit http://localhost:5173
in your browser. You should see a beautifully styled page with gradients, shadows, and hover effects!
Why the .cjs Extension Works
The .cjs
extension tells Node.js to treat the file as a CommonJS module, regardless of the "type": "module"
setting in package.json
. This allows you to:
- Keep using familiar
module.exports
syntax - Avoid ES module conversion
- Maintain compatibility with tools that expect CommonJS configs
Alternative Solution: ES Module Syntax
If you prefer to use ES modules, you can keep the .js
extensions and convert the syntax:
postcss.config.js:
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
tailwind.config.js:
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
Common Issues and Solutions
Issue 1: Styles Not Applying
Solution: Check that your content paths in tailwind.config.cjs
match your file structure.
Issue 2: Config File Not Found
Solution: Ensure config files are in your project root directory, not in subdirectories.
Issue 3: CSS Not Loading
Solution: Verify that you're importing ./index.css
in your main.jsx
file.
Summary
Here's what we accomplished:
- β Created a new React project with Vite
- β Installed Tailwind CSS and dependencies
- β Generated configuration files
- β
Fixed the ES module conflict by using
.cjs
extensions - β Added Tailwind directives to CSS
- β Tested the setup with a sample component
Next Steps
Now that Tailwind CSS is working, you can:
- Explore Tailwind's utility classes
- Customize your theme in
tailwind.config.cjs
- Add Tailwind plugins
- Build amazing UIs with utility-first CSS
The key takeaway is remembering to use .cjs
extensions for config files when working with Vite projects. This simple change prevents the ES module conflict and gets you up and running quickly!
Happy coding! π
Top comments (0)