Introduction
What Tailwind CSS is, how the v4 architecture differs from v3, and when a utility-first framework is — and is not — the right choice.
Tailwind CSS is a utility-first CSS framework. Instead of shipping pre-built components like .btn or .card, it ships thousands of small single-purpose classes — flex, pt-4, text-sm, bg-white — that you compose directly in your markup.
Overview#
A traditional stylesheet asks you to invent a name for every piece of UI, then keep that name and its styles in sync as the design changes. Tailwind removes the naming step entirely: you describe the result in the markup, and the framework generates exactly the CSS you used.
<!-- Traditional: two files, one invented name -->
<button class="btn-primary">Save changes</button>
<!-- Tailwind: one file, no naming -->
<button class="rounded-md bg-indigo-600 px-4 py-2 font-medium text-white hover:bg-indigo-500">
Save changes
</button>The second version is longer, but it is also complete. There is no other file to open, no risk that editing .btn-primary breaks a page you forgot about, and no dead CSS left behind when the button is deleted.
Why it exists#
Utility classes solve four problems that grow with a codebase:
- Naming fatigue.
.card,.card-inner,.card-inner-header— naming is the slowest part of writing CSS, and the names carry no information. - Unbounded stylesheet growth. Traditional CSS grows with every feature. Utility CSS plateaus, because the tenth card reuses the same classes as the first.
- Fear of deletion. Nobody deletes CSS they did not write, so stylesheets accumulate. Deleting markup deletes its styles.
- Inconsistent design. Utilities are generated from a constrained token scale, so
p-4is the same spacing everywhere. Ad-hoc CSS drifts to15px,16px,1rem,0.95rem.
What is new in v4#
Tailwind v4 (January 2025) rewrote the engine and moved configuration out of JavaScript and into CSS. v4.3 is the current stable line.
CSS-first configuration#
tailwind.config.js is gone from the default workflow. Design tokens are declared with the @theme directive in your stylesheet, and every token is also emitted as a real CSS custom property.
@import "tailwindcss";
@theme {
--color-brand: oklch(0.62 0.19 264);
--font-display: "Satoshi", sans-serif;
--breakpoint-3xl: 120rem;
}That gives you bg-brand, text-brand, font-display and 3xl:* — plus var(--color-brand) usable from any hand-written CSS, inline style or JavaScript animation.
A single import#
/* v4 */
@import "tailwindcss";@tailwind base;
@tailwind components;
@tailwind utilities;Automatic source detection#
v3 required a content array listing every template glob. v4 discovers your source files automatically, respecting .gitignore and skipping binary files. You only reach for @source when scanning something outside the project, such as a component library in node_modules.
Built on modern CSS#
The engine now leans on platform features rather than reimplementing them:
| Feature | Used for |
|---|---|
| Native cascade layers | Predictable ordering between base, components and utilities |
@property | Animatable, type-safe transforms and gradients |
color-mix() | The /50 opacity modifier on any colour |
oklch() | A wider, perceptually even default palette |
| Container queries | @container and @sm:* with no plugin |
Version timeline#
| Version | Released | Headline |
|---|---|---|
| v1.0 | May 2019 | First stable release |
| v2.0 | Nov 2020 | Dark mode, extended palette |
| v3.0 | Dec 2021 | JIT engine by default, arbitrary values |
| v4.0 | Jan 2025 | New engine, CSS-first config, container queries |
| v4.1 | Apr 2025 | Text shadows, masks, safe alignment, pointer variants |
| v4.3 | May 2026 | Scrollbar utilities, zoom-*, tab-*, four new palettes |
When to use Tailwind#
Good fit
- Product UI built from components — React, Vue, Svelte, Blade, ERB.
- Design systems where consistency matters more than novel per-page styling.
- Teams that want to delete UI confidently.
- Projects where CSS bundle size has become a problem.
Poor fit
- Content you do not control, such as CMS-authored HTML. Use the typography plugin or plain CSS there.
- Email templates. Most clients need inlined styles.
- A single page with a handful of rules — a
<style>block is less machinery. - Environments where you cannot run a build step and cannot ship the Play CDN.
Common mistakes#
- Treating long class lists as a smell. Repetition is a signal to extract a component, not a CSS class. See Utility-First CSS.
- Reaching for
@applyimmediately. It rebuilds the maintenance problem Tailwind removes. It has narrow legitimate uses, covered in Custom Utilities. - Following a v3 tutorial on a v4 project. Most of the internet still shows
tailwind.config.js. Check Deprecated APIs when a snippet does not work.
Related topics#
- Installation — get a build running
- Your First Utilities — read a class name
- Theme & Design Tokens — configure v4
- v3 → v4 Migration — upgrade an existing project