Eliminating CSS Bloat with Tailwind CSS JIT Mode
Stop managing massive CSS files and fragile purge configurations. Learn how Tailwind CSS JIT mode generates styles on-demand and enables arbitrary values for a leaner production build.
08 Jul 2025, 23:06 UTC

The Problem: The 'Purge' Workflow Bottleneck
In early versions of Tailwind CSS, the development experience was split into two distinct worlds. During development, the engine generated every possible utility class—thousands of lines of CSS—to ensure you had everything available. For production, you had to configure a "purge" step (usually via PurgeCSS) to scan your HTML and strip away the unused styles. This created a disconnect: your dev environment was bloated, and your production build required a separate, sometimes fragile, cleanup process that could accidentally remove necessary styles if the configuration was slightly off.
The Just-In-Time (JIT) engine, which became the default in Tailwind CSS v3.0, solves this by flipping the logic. Instead of generating everything and then deleting the excess, JIT generates only the CSS you actually use, the moment you write the class in your code.
How the JIT Engine Operates
The JIT compiler functions as a watcher. It monitors the files defined in the content array of your tailwind.config.js. When you save a file containing a class like text-center, the compiler detects that string, generates the corresponding CSS rule, and injects it into the stylesheet instantly.
Arbitrary Values: Breaking the Design System
One of the most practical engineering shifts brought by JIT is the support for arbitrary values. Previously, if you needed a specific width—say, 123 pixels—that wasn't in your theme, you had to add it to the config file or use an inline style. JIT allows you to use square bracket notation to generate a one-off utility on the fly.
<div class="w-[123px] bg-[#bada55] mt-[-12px]">
Custom Sized Element
</div>The compiler sees w-[123px] and immediately generates .w-\[123px\] { width: 123px; }. This keeps your configuration file clean while providing the flexibility of raw CSS.
Implementation and Verification
To use JIT in a modern project (v3.0+), ensure your tailwind.config.js correctly identifies your template files. This is where the scanner looks for class names.
Configuration Example
// tailwind.config.js
module.exports = {
content: [
'./src/**/*.{html,js,jsx,ts,tsx}', // Scan all these extensions in src
],
theme: {
extend: {},
},
plugins: [],
}Verifying the JIT Process
To confirm that the JIT engine is actively scanning and generating styles rather than serving a static blob, run the Tailwind CLI with the --verbose flag from your terminal (requires Node.js installed):
npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch --verboseExpected Result: You should see log entries confirming content scanning and on-demand CSS generation whenever you save a file. Additionally, if you open output.css, you will notice the file size is remarkably small—containing only the specific utilities used in your markup rather than the entire Tailwind library.
Trade-offs and Limitations
While JIT significantly speeds up the feedback loop, it introduces a few specific constraints:
- Dynamic Class Names: The JIT engine does not execute your JavaScript. It performs a static string analysis. If you construct class names using string interpolation (e.g.,
<div class="text-${color}-500">), the compiler will not find those classes and will not generate the CSS. You must use full class names or a lookup table. - Memory Usage in Monorepos: Because the scanner must index all files in the
contentarray, extremely large monorepos can see increased memory consumption during the initial startup. If you encounter "Out of Memory" errors, refine yourcontentpaths to be as specific as possible. - Plugin Compatibility: Some older third-party plugins built for the classic static generation pipeline may require updates to work correctly with the JIT engine.
Closing Action
If you are still using a legacy Tailwind v2 setup with a separate PurgeCSS config, migrating to v3.0+ is the single most effective way to reduce build times and CSS bundle size. Audit your content array to ensure no unnecessary directories are being scanned, and start leveraging arbitrary values to remove redundant custom CSS files from your project.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.