If you're looking to seamlessly integrate Tailwind into your workflow, the recommended approach is to utilize their CLI as outlined in their documentation. However, I also explore an alternative method of integrating PostCSS with esbuild to run Tailwind.
Method 1: Leveraging the Tailwind CLI
This method stands out for its simplicity and does not necessitate PostCSS or any esbuild configurations. It is advisable if you don't specifically require other PostCSS functionalities.
To get started, follow the installation instructions provided in the documentation.
npm install -D tailwindcss
npx tailwindcss init
Remember to set up your content
keys in your tailwind.config.js
.
To build using their CLI, execute the following command (adjusting the path as needed for your project).
npx tailwindcss -i ./src/app.css -o ./public/app.css --minify
You can even combine your esbuild and Tailwind processes by utilizing npm-run-all
.
npm I -D npm-run-all
{
"scripts": {
"build:esbuild": "node ./esbuild.config.js",
"build:css": "npx tailwindcss -i ./src/app.css -o ./public/app.css --minify",
"build": "npm-run-all --parallel build:*"
},
}
A similar setup can be applied for monitoring your development server.
{
"scripts": {
"build:esbuild": "node ./esbuild.config.js",
"build:css": "npx tailwindcss -i ./src/app.css -o ./public/app.css --minify",
"build": "npm-run-all --parallel build:*",
"watch:esbuild": "node ./esbuild.serve.js",
"watch:css": "npx tailwindcss -i ./src/app.css -o ./public/app.css --watch",
"dev": "npm-run-all --parallel watch:*"
},
}
Method 2: Implementing PostCSS
Conversely, if you are crafting custom CSS and need PostCSS capabilities, or opt to employ esbuild for CSS generation, running Tailwind as a PostCSS plugin alongside esbuild is feasible.
While there isn't a widely maintained standard esbuild plugin for PostCSS, trial different plugins until you find one that suits your needs. One option worth considering is esbuild-style-plugin
.
To incorporate this plugin with Tailwind, install Tailwind (refer to their PostCSS installation guidelines).
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
Set up your tailwind.config.js
, but you won't need a postcss.config.js
as that will be configured with esbuild-style-plugin
.
Install it:
npm i -D esbuild-style-plugin
Your esbuild configuration will resemble the following (add additional options according to your requirements):
const postCssPlugin = require('esbuild-style-plugin')
require('esbuild')
.build({
entryPoints: ['src/app.jsx', 'src/style.css'],
outdir: 'public',
bundle: true,
minify: true,
plugins: [
postCssPlugin({
postcss: {
plugins: [require('tailwindcss'), require('autoprefixer')],
},
}),
],
})
.catch(() => {
console.error(`Build error: ${error}`)
process.exit(1)
})
Note how we configure our PostCSS plugins here. The plugin also offers additional options for CSS modules or other preprocessors like SASS or LESS.
One aspect to keep in mind is that this plugin may produce a .js
file with the same name as your CSS file. To avoid conflicts, consider renaming either the CSS or JS file, or import the CSS file in your JS file (e.g., import './app.css'
at the beginning of app.tsx
). If opting for imports, remember to exclude app.css
from your esbuild config's entrypoints.
I achieved functionality with a basic example (GitHub repository) when originally drafting this answer. Your scenario may have unique challenges, so if viable, I recommend the former method as it reduces dependencies on your bundler.