This episode dissects how Tailwind works behind the scenes: utility generation via the JIT engine, content scanning, and the structure of tailwind.config.js. You also learn the core @tailwind and @apply directives, as well as the first official plugins you should know.

Before writing lots of utility classes, you need to understand how Tailwind works. Episode 2 dissects the main architecture: the CSS generation engine, how Tailwind scans files, the structure of tailwind.config.js, and the core directives that are the entry point of every project.
This understanding isn't just theory. When JIT doesn't generate the class you expect, or when CSS size balloons, the root cause is almost always in one of the three things we'll cover: content paths, theme config, and directives. After this episode, you'll know exactly where to look.
Since version 3, Tailwind uses a just-in-time (JIT) engine. Instead of generating thousands of utilities that might be used, JIT generates CSS only for the classes that actually appear. The result: a very small output size, and you can use arbitrary values like p-[13px] without extra configuration.
Arbitrary classes are written in square brackets — for example text-[14px] or w-[calc(100%-1rem)] — and are only generated if they actually appear in a scanned file.
JIT needs to know which files to scan for class names. This is controlled via the content option in the config:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./index.html", "./src/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
};The array content: ["./index.html", "./src/**/*.{js,jsx,ts,tsx}"] tells Tailwind which globs to scan. Files outside these patterns won't contribute to the final CSS — this is the root of many "class not appearing" mysteries.
Already covered above. General recommendation: include every file that contains class names, including templates, components, and markdown files. The narrower and more precise the glob pattern, the faster the build and the smaller the generated CSS.
The theme section defines design tokens like colors, spacing, fonts, and breakpoints. theme.extend adds or changes tokens without removing the defaults. Meanwhile, variants (deprecated in newer versions) controls when variants like hover or md are generated — in modern versions, most of this is controlled directly through utility prefixes.
plugins is where you register external plugins like @tailwindcss/forms. safelist forces a set of classes to always be generated even if they aren't detected in content — important for dynamic classes, and covered in episodes 8 and 11.
Every Tailwind project starts from a CSS file that contains these three directives:
@tailwind base;
@tailwind components;
@tailwind utilities;@tailwind base injects preflight — cross-browser style normalization like a modern reset.@tailwind components provides a place for component classes and component plugins.@tailwind utilities holds all the utility classes generated by JIT.The order matters because it determines the declaration order and the cascade. Don't swap their positions without a reason.
The @apply directive lets you inline utility classes into your own CSS rules:
.btn-primary {
@apply rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600;
}@apply hover:bg-blue-600 includes a hover variant inside the rule. This is the bridge between utility classes and custom CSS — covered in more depth in episode 7.
The four most commonly used official plugins:
@tailwindcss/forms — reset and consistent styling for form elements.@tailwindcss/typography — the prose class for rich content like blog articles.@tailwindcss/aspect-ratio — deterministic aspect ratios, now core utilities.@tailwindcss/line-clamp — truncating multi-line text, also in core since 3.3.Installing them is simple:
npm install -D @tailwindcss/forms @tailwindcss/typographyThen register them in the plugins array of the config. Episode 9 will cover custom plugins and the ecosystem in full.
Tip
Before installing a plugin, check the docs for your Tailwind version. Some features that used to be plugins — like aspect-ratio and line-clamp — are now core utilities in newer versions, so the plugins are no longer needed.
Episode 2 provided the architectural foundation: how JIT generates CSS only for detected classes, how content determines what gets scanned, the config structure, and the role of the @tailwind and @apply directives.
Key takeaways:
content determines which files get scanned; a wrong glob means missing classes.theme.extend adds tokens without removing defaults.base, components, utilities affects the cascade.@apply inlines utility classes into custom CSS.Next, in episode 3, we'll get started quickly: choosing an installation method (CLI, PostCSS, or framework), writing a minimal tailwind.config.js, and running the development workflow with --watch. All this architectural knowledge will be put straight into practice.