Mastering Tailwind CSS JIT: On‑Demand Class Generation & Real‑Time Feedback
Tailwind CSS’s Just‑In‑Time mode compiles only the utilities you use, shrinking bundles and speeding builds. Learn how to configure the content array, handle dynamic classes, and watch for instant feedback in this practical guide.
01 Oct 2025, 22:20 UTC

Why Tailwind’s JIT Matters
When a project grows, the default Tailwind build often produces a CSS file that is hundreds of kilobytes, even though only a fraction of the utilities are actually used. Build times also climb as the compiler scans every file for class names. Tailwind’s Just‑In‑Time (JIT) mode addresses both problems by compiling CSS only for classes that appear in your source files and by updating the bundle on the fly as you type.
How JIT Works
JIT is the default compiler in Tailwind 3.x. Instead of generating a static stylesheet at the start, it watches your source tree, parses the classes it sees, and emits the corresponding CSS immediately. This incremental process means:
- Smaller output – only used utilities are included.
- Faster builds – the compiler skips unused files.
- Live feedback – new classes appear in the page as soon as you save.
Configuring the content Array
JIT relies on a content array in tailwind.config.js to know where to look for class names. A mis‑configured path can either drop styles or bloat the bundle.
module.exports = {
content: [
'./src/**/*.{html,js,ts,tsx}', // Adjust to your project structure
],
theme: {
extend: {},
},
plugins: [],
}
Run npx tailwindcss -v to confirm you’re on 3.x or newer; older versions will trigger a warning that JIT is required.
Dealing with Dynamic Class Names
JIT can’t resolve class names that are constructed at runtime, such as bg-${color}. If you need these, you must add them to the safelist or write them in a pattern that the scanner can pick up.
module.exports = {
content: [
'./src/**/*.{html,js,ts,tsx}',
],
safelist: [
{ pattern: /bg-(red|green|blue)-\d{3}/ },
'text-center',
],
}
Without safelisting, the generated CSS will omit those utilities, leading to broken styles.
Hands‑On Example: Watching a Component
- Create a simple component in
src/App.jsx:export default function App() { return ( <div className="p-4 bg-blue-200 text-gray-800"> Hello, Tailwind JIT! </div> ); } - Run the CLI in watch mode:
npx tailwindcss -i src/input.css -o dist/output.css --watch - Open
dist/output.cssin the browser. As you add a new class, such astext-lg, the CSS file instantly updates, and the browser reflects the change without a full rebuild.
Check the console for the compiled CSS snippet to verify that the class was generated. If it’s missing, double‑check that the file containing the class is within the content paths.
Trade‑Offs & Limitations
- Broad
contentpaths can still produce large bundles if many files contain arbitrary strings. - Dynamic classes require explicit safelisting; otherwise they’re omitted.
- Legacy build tools may need updates to support the CLI’s new syntax; ensure your bundler is compatible with Tailwind 3.x.
- Because JIT generates CSS on the fly, a misconfigured purge can lead to runtime errors if a class is referenced but not compiled.
Actionable Next Steps
1. Upgrade to Tailwind 3.x if you haven’t already.
2. Add a precise content array that covers all template files.
3. Identify any dynamic class patterns and safelist them.
4. Run the CLI in --watch mode during development to enjoy instant feedback.
With these steps, you’ll enjoy lean CSS bundles, faster builds, and a smoother development experience.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.