Tailwind CSS styles elements through small single-purpose classes written in the markup, then compiles a stylesheet that holds only the classes a project actually uses. Tailwind Labs maintains it under the MIT License.

Frontend teams use it to build custom interfaces without writing a separate rule for every component. The npm registry recorded 134,233,744 downloads of the package for October 2 to 8, 2026.

A heads-up if you follow older tutorials. Guides written for v3 start from a tailwind.config.js file, and projects on v4 no longer need one, because theme variables now live in the stylesheet.

What Is Tailwind CSS?

Tailwind scans your files for class names and generates CSS for the ones it recognizes, so the stylesheet never contains anything you didn’t use.

A class such as bg-sky-500 sets one background color and nothing else. To style a button, you list classes on the element in your HTML.

The core framework ships no prebuilt buttons or cards, and no navbars either. That’s the main difference from Bootstrap, which supplies finished components. Tailwind only gives you the individual style rules, and putting them together is your job.

What utility-first means

Each class does one job, and the styling sits in the markup instead of in a separate rule per component.

In traditional CSS, one class like .btn holds the base color and the hover color together. Tailwind splits that into bg-sky-500 and hover:bg-sky-700, and the second one does nothing until the element is hovered.

The Tailwind documentation lists these benefits of working this way:

  • no time spent inventing class names or switching between HTML and CSS files
  • edits that touch one element only
  • easier maintenance on old projects
  • markup that copies cleanly between projects
  • a stylesheet that stops growing with every new feature

Those are the maintainers’ own claims, not measurements. Worth keeping that in mind.

Who makes Tailwind CSS

Adam Wathan announced version 0.1.0 on November 1, 2017 and tagged v1.0 on May 13, 2019, according to his own history of the project.

It grew out of utility styles he kept carrying from one abandoned side project to the next, first Digest and then KiteTail. Jonathan Reinink tried it on a second codebase with a different design, which forced it to work beyond a single project. David Hemphill later suggested rebuilding the early Less version on PostCSS, and that’s why Tailwind shipped as a PostCSS plugin for years.

Where is web design headed next?

Discover the latest web design statistics: industry growth, design trends, technology adoption, and insights defining the future of the web.

Explore the Data →

Tailwind Labs, the company Wathan built with business partner Steve Schoger, maintains the framework. On September 9, 2026, Tailwind Labs announced that it is joining Shopify. Tailwind CSS stays MIT-licensed, and the Tailwind Labs team continues to maintain it.

How Tailwind CSS Turns Class Names Into a Stylesheet

Tailwind reads project files as plain text, collects every string that could be a class name, and writes CSS only for the strings that match a known utility.

The output is one static stylesheet with zero runtime, per the Tailwind installation docs.

Scanning and output

The scanner never parses code. It matches tokens against the characters a class name can contain and throws away any token that maps to no utility.

That’s also what makes arbitrary values like bg-[#316ff6] possible, since the CSS is generated from the class name itself.

By default the scanner skips files listed in .gitignore, the node_modules directory, binary files such as images and zip archives, CSS files, and package manager lock files.

The @source directive registers anything on that list. You’ll need it for a UI library that’s installed under node_modules and built with Tailwind.

Just-in-time generation became the only engine in v3.0 on December 9, 2021, replacing the classic engine (Tailwind CSS blog).

Preflight

Tailwind injects a base style reset called Preflight into the base layer, and it’s built on modern-normalize.

Most of it goes unnoticed. A handful of resets surprise people first, and they’re all in this table.

ElementPreflight defaultRestore with
MarginsRemoved from every elementSpacing utilities such as mt-4
HeadingsSame size and weight as body textText and font utilities, or custom base styles
ListsNo bullets or numberslist-disc with list-inside
Images and videodisplay: block, max-width 100%inline or max-w-none
BordersWidth 0, solid styleborder (adds 1px in currentColor)

VoiceOver doesn’t announce unstyled lists as lists. Adding an ARIA list role to the element fixes that.

To drop Preflight, import the theme and utilities files from tailwindcss separately and leave the Preflight file out.

Since v4.0, buttons also keep the browser’s default cursor instead of a pointer.

Classes the scanner cannot see

Tailwind writes CSS for a class only when the complete class name appears in a file exactly as spelled.

Something like bg-${color}-600, built at runtime from a prop, breaks. The strings bg-red-600 and bg-blue-600 never exist in the source, so no CSS is generated for them. A lookup object that maps each prop value to a complete class string works fine, such as blue mapped to “bg-blue-600 hover:bg-blue-500”.

For a class that has to exist without appearing in any file, @source inline() forces it into the output.

What Changed in Tailwind CSS v4

Version 4 swapped the engine for a rewritten one, moved configuration from a JavaScript file into the stylesheet, and raised the minimum browser versions.

It was released on January 22, 2025 (Tailwind CSS blog). Measured on the Catalyst UI kit, a full build took 378 ms in v3.4 and 100 ms in v4.0. The browser baseline is Chrome 111, Safari 16.4 and Firefox 128 (Tailwind CSS compatibility docs). The docs currently cover v4.3, first released May 8, 2026.

The announcement gives two sets of speed numbers. Its summary says full builds are up to 5x faster, while its own benchmark shows 3.78x for a full build, 8.8x for an incremental build that adds CSS and 182x for one that adds none.

The engine is called Oxide. Wathan previewed it at Tailwind Connect in 2023, and the first public alpha followed on March 6, 2024.

It was planned as a v3.x release, but the rewrite felt like a new generation, so it became v4. In the alpha, the costliest parts moved to Rust, the core stayed in TypeScript, and Lightning CSS was the only dependency.

CSS-first configuration and theme variables

New projects don’t need tailwind.config.js. Design tokens live in the stylesheet, inside an @theme block.

A theme variable does two jobs at once, per the Tailwind documentation. It creates utility classes, and it emits a regular CSS custom property.

  • –color-mint-500 produces bg-mint-500, text-mint-500 and fill-mint-500
  • –breakpoint-3xl produces a 3xl: variant
  • every theme variable is also a CSS custom property, readable in inline styles or animation libraries

Variables that shouldn’t produce utilities belong in :root instead.

Imports changed too. A single @import “tailwindcss” replaces the three @tailwind directives, and Lightning CSS now handles vendor prefixing and nesting, so autoprefixer and postcss-import drop out of the build.

The content array is gone as well. v4 finds template files itself and skips .gitignore entries and binary files.

Existing configs still load through the @config directive, but v4 no longer detects them automatically. The corePlugins, safelist and separator options aren’t supported.

Browser baseline and version choice

Tailwind CSS v4 depends on @property and color-mix() for core features, and the upgrade guide states it won’t work in older browsers.

If every browser in your analytics clears that baseline, go with v4. If older browsers still need to work, stay on v3.4, which is exactly what the upgrade guide recommends.

Checking your audience’s browser share against the baseline matters more than the speed gain, because cross-browser compatibility is the one thing v4 can’t fix for you.

How long v3.4 stays supported is less clear. As of October 2026, endoflife.date lists support through February 28, 2027 and notes that the date comes from a remark by the creator, not from documentation. Versionlog states that Tailwind Labs has published no support window for any version.

Responsive Design, States, and Dark Mode With Variants

A variant is a prefix that makes a utility apply only under a condition, whether that’s a breakpoint, an interaction state or a color scheme.

md:flex applies at 48rem and wider, hover:bg-sky-700 on hover, dark:bg-gray-800 in dark mode. Variants stack, so dark:md:hover:bg-fuchsia-600 combines all three.

Breakpoints and mobile-first prefixes

The defaults are in the table below. Each prefix compiles to a min-width media query, so md:flex means flex at 48rem and above.

PrefixMinimum widthPixels
sm40rem640px
md48rem768px
lg64rem1024px
xl80rem1280px
2xl96rem1536px

Unprefixed utilities apply at every size, and prefixed ones apply at that width and up. That’s the standard mobile-first design approach.

A common mistake is reading sm: as “small screens”. It means 640px and up. To center text on mobile and left-align it from 640px, write text-center sm:text-left.

  • md:max-xl:flex limits a style to a width range
  • –breakpoint-3xl in @theme adds a custom breakpoint, and it needs the same unit as the defaults (rem), or the generated utilities sort in the wrong order
  • @container with @sm and @md variants styles elements by parent size, built into core since v4

State variants

Every utility takes a state prefix, and the prefix does the targeting.

The variants group roughly by the kind of selector underneath:

  • pseudo-classes such as hover, focus, first and required
  • pseudo-elements such as before, after, placeholder and selection
  • media and feature queries such as breakpoints, dark and motion-reduce
  • attribute selectors such as aria-checked, data-* and open
  • child selectors through the * and ** variants

The group and peer variants style an element from a parent or an earlier sibling, so a card can change when its container is hovered. Peer only works from earlier siblings, which is a limit of the CSS sibling combinator.

One behavior changed in v4.0. Hover now applies only on devices that report hover support, through @media (hover: hover). A design that relies on a tap triggering hover breaks on touch screens unless the variant is redefined with @custom-variant hover (&:hover).

Stacked variants also apply left to right in v4, reversed from v3, which mostly affects the * child variant.

Dark mode

By default, the dark: variant follows the operating system through prefers-color-scheme.

A single utility never holds both values. You write bg-white dark:bg-gray-800, one class for each mode.

To drive dark mode from a toggle instead, override the variant with @custom-variant dark (&:where(.dark, .dark *)) and add the dark class to the html element. A data-theme attribute works the same way with a different selector.

Tailwind’s documentation adds one practical note. Set the class from an inline script in the head, before first paint, so people don’t see a flash of the wrong theme.

How to Install Tailwind CSS

For most projects, the Vite plugin is the way to go. Add tailwindcss and @tailwindcss/vite with npm, register the plugin in the Vite config, and import tailwindcss in your main stylesheet.

PostCSS, a standalone CLI and a webpack plugin cover everything Vite doesn’t.

Pick an install method

Tailwind CSS ships a separate package for each build setup, and the official docs name the frameworks each one suits.

MethodPackageUse it for
Vite plugin@tailwindcss/viteLaravel, SvelteKit, React Router, Nuxt, SolidJS
PostCSS plugin@tailwindcss/postcssNext.js, Angular
CLI@tailwindcss/cliGetting started without a bundler or framework build step
Webpack plugin@tailwindcss/webpackwebpack builds (added in v4.2.0)
Play CDN@tailwindcss/browserExperiments only

The Play CDN is meant for development, and the docs state it isn’t intended for production.

The CLI also exists as a standalone executable, so it runs without Node.js. For a quick test with nothing installed, Tailwind Play runs in the browser.

Install with Vite

These steps come from the official installation guide.

  1. Create a project with npm create vite@latest my-project, then move into the folder.
  2. Run npm install tailwindcss @tailwindcss/vite.
  3. Add the @tailwindcss/vite plugin to vite.config.
  4. Add @import “tailwindcss” to your main CSS file.
  5. Run npm run dev to start the build process.
  6. Link the compiled CSS in the head (many frameworks do this for you) and start writing utility classes.

Once the first styled heading renders, the next job is building real components, and this guide to putting Tailwind to work in a project picks up from there.

Set up the editor

Tailwind uses custom CSS syntax such as @theme, @variant and @source, and some editors flag those rules as errors.

The official VS Code extension, Tailwind CSS IntelliSense, adds a Tailwind language mode, autocomplete, linting, hover previews and syntax highlighting. Zed has autocomplete, linting and hover previews built in. prettier-plugin-tailwindcss sorts classes into the recommended order and works anywhere Prettier runs.

JetBrains IDEs such as WebStorm include Tailwind completions, and Cursor runs the VS Code extension. In some editors, native CSS validation has to be switched off as well, according to the docs.

Tailwind CSS vs Bootstrap and Plain CSS

Bootstrap ships finished components and plain CSS ships nothing prebuilt. Tailwind sits between them, with style primitives and no components. Which one fits depends on how much of the design is yours.

DimensionTailwind CSSBootstrapPlain CSS
Styling unitSingle-purpose utility classesComponent classes and helpersYour own rules and selectors
Where components come fromHeadless UI, shadcn/ui, community kits (Tailwind Plus is closed to new customers)Bundled in the frameworkYou build them
JavaScriptNone at runtimeBootstrap’s JavaScript plugins for modals, dropdowns and tooltips; the bundle build includes PopperYour own
Customization routeTheme variables in CSSSass variables or CSS custom propertiesEdit the rules directly
Stylesheet deliveryGenerated from the classes you usePrebuilt file, via CDN or compiledWhatever you write

Tailwind CSS vs Bootstrap

Tailwind makes sense when the design is custom and no component set should dictate its look. Bootstrap makes more sense when a recognizable, ready-made interface is acceptable and getting to a working page quickly matters more than a distinct look.

Both are mobile-first, so that’s not what decides it.

In the npm registry, tailwindcss recorded 134,233,744 downloads for October 2 to 8, 2026, against 5,811,372 for bootstrap, about 23 times as many.

W3Techs shows the reverse picture on live sites. Bootstrap sits on 13.3% of websites as of October 10, 2026, and Tailwind on 0.3%.

The two figures measure different things. npm counts installs, automated ones included, while W3Techs detects frameworks on public pages.

Secondary write-ups of the State of CSS 2025 survey disagree with each other on satisfaction and usage, so survey percentages stay out of this comparison.

For a longer side-by-side, see this comparison of Tailwind and Bootstrap.

Tailwind CSS vs plain CSS and BEM

Plain CSS keeps the HTML clean and moves the work into naming.

BEM is the best-known convention for that. Classes are named block__element–modifier (form__submit–disabled, for example), which keeps hand-written rules predictable.

Utilities remove the naming step, and the cost moves into longer class attributes in the markup.

Most published page-weight comparisons between the two approaches come from secondary blog posts, so measure your own build before treating either one as smaller.

A deeper look at the trade sits in this article on Tailwind CSS versus writing CSS directly.

Other utility-first options

Tachyons is a functional CSS toolkit, listed at v4.12.0 on its site, and it ships one prebuilt stylesheet that its authors put at under 14 kB minified and gzipped.

UnoCSS comes from Anthony Fu under the MIT License. It’s an on-demand atomic CSS engine with an un-opinionated core, and utilities arrive through presets.

The split matters for tooling. Tachyons is a fixed file you strip by hand, while UnoCSS and Tailwind generate CSS from the classes they find.

When Tailwind CSS Does Not Fit a Project

Tailwind fits poorly when a stylesheet has to stay on Sass, Less or Stylus. It also struggles in codebases built on CSS modules or per-component style blocks, and on pages small enough that a few plain rules finish the job.

Preprocessors and CSS modules

Tailwind v4 isn’t designed for Sass, Less or Stylus. The docs tell you to treat Tailwind itself as the preprocessor, so a stylesheet that depends on Sass gets rewritten, not combined.

Teams weighing the switch can read this comparison of Tailwind and Sass.

Each Sass habit has a native replacement:

  • loops give way to classes generated on demand
  • darken and lighten give way to palette shades or color-mix()
  • min(), max() and round() are native browser math functions

CSS modules are the second trap, because build tools process each module separately. With 50 CSS modules, Tailwind runs 50 separate times, which slows builds, according to the Tailwind compatibility docs.

Modules also lose access to theme variables, so @apply needs an @reference import of the global stylesheet. The docs recommend avoiding style blocks in Vue, Svelte and Astro components for the same reason.

Repeated class lists and @apply

Long class lists repeat when the same element shows up in many places. The Tailwind docs suggest fixes in order of effort.

  1. Render the element in a loop, so the class list is written once.
  2. Use multi-cursor editing when the duplication sits in one file.
  3. Extract a component or template partial when the styles repeat across files.
  4. Write a custom CSS class in the components layer, built on theme variables, when a partial feels too heavy.

Reach for @apply last. A class that wraps utilities brings back the naming step Tailwind removed.

Projects where plain CSS is enough

A single page with a dozen rules gains nothing from a utility framework.

Plain CSS needs no build step, no editor extension and no class-sorting plugin. At that size, all of those are overhead.

The reverse holds for knowledge, too. Utilities map one-to-one to CSS properties, so a developer who doesn’t know what flex-direction does won’t get far with flex-col.

Is Tailwind CSS Free?

Yes. The framework is released under the MIT License, copyright Tailwind Labs, Inc., so using it in personal and commercial projects costs nothing.

License and what costs money

The MIT License covers the framework itself, per the LICENSE file in the GitHub repository. The documentation site is different. Its repository states it isn’t under an open-source license and remains the property of Tailwind Labs Inc.

Tailwind Plus is the paid part, a library of components, templates and the Catalyst UI kit. It was sold as a one-time purchase with lifetime access until Tailwind Labs closed it to new customers on September 9, 2026. Existing customers keep their access.

Tailwind Plus is the new name for Tailwind UI, changed on March 4, 2025. Tailwind Labs said then that there was no subscription pricing and no upgrade cost for existing license holders.

Tailwind Labs funding and project health

Adam Wathan said in a GitHub comment in early January 2026 that 75% of the engineering team had lost their jobs the day before, that documentation traffic was down about 40% from early 2023, and that revenue was down close to 80%.

He blamed the impact of AI on the business. eWeek reported the mechanism: AI coding tools generate Tailwind code, so many developers never visit the docs where the paid products are promoted.

The framework kept shipping. v4.2.0 followed on February 18, 2026, about six weeks later.

On September 9, 2026, Tailwind Labs announced that it is joining Shopify. The announcement said the open-source projects stay MIT-licensed, and that the company would stop trying to grow the business around Tailwind, so new sign-ups for Tailwind Plus and ui.sh closed the same day. Existing customers keep their access.

As of October 2026, the Tailwind CSS partners page lists Vercel, Google AI Studio, Lovable, Cursor and Shopify among its partners. The page still carries the line that Tailwind CSS is not owned by a big tech company, and it asks for sponsorship to fund the small team behind the framework.

Sponsorship is now the funding route that page describes, because the Tailwind Plus license Wathan pointed users to in January is no longer sold to new customers.

For adoption risk, the MIT License and a dated release record are the checkable facts. Headcount isn’t.

Component libraries around Tailwind CSS

Tailwind Labs makes Headless UI, a set of unstyled, accessible components for React and Vue, and Heroicons, MIT-licensed SVG icons in outline, solid, mini and micro styles.

shadcn/ui copies component source into your project through a CLI, and its docs say it is not a component library.

daisyUI is a free Tailwind plugin that adds semantic class names such as btn and card, with no JavaScript. Its own demo shows the trade. A form that takes 114 class names in plain Tailwind takes 14 with daisyUI, according to the project’s site.

The cost is a second vocabulary to learn and a dependency on a third-party plugin.

Tailwind CSS FAQ

Is Tailwind CSS the same as inline styles?

No. Inline styles can’t target hover or focus states or media queries, and every value in them is a magic number. Utilities draw from a predefined theme and carry variants.

Inline styles still fit values that come from a database or an API, according to the Tailwind documentation.

Does Tailwind CSS replace knowing CSS?

No. When two utilities set the same property, the one that appears later in the generated stylesheet wins, not the one that comes later in the class attribute (Tailwind CSS docs).

Predicting that order, and writing arbitrary variants with raw selectors, takes working knowledge of the cascade and specificity.

How long does it take to learn Tailwind CSS?

No official source gives a learning time, so treat any week count you see as an estimate.

Editor tooling shortens the loop. IntelliSense hover previews show the CSS behind each class, and autocomplete lists the available utilities.

Can Tailwind CSS handle large projects?

Yes, with conditions. The documentation says the benefits grow on long-running projects at scale, though that’s the maintainers’ view, not a benchmark.

Theme variables can sit in a shared CSS file that each project imports, or that a team publishes to npm, which keeps tokens consistent across a monorepo.

Does Tailwind CSS work with React, Vue and Next.js?

Yes. Tailwind CSS has no framework dependency, and the official framework guides cover Next.js, Nuxt, SvelteKit and Laravel.

In React or Vue, move repeated class lists into components. This walkthrough of using Tailwind CSS in React shows the pattern.

How do I upgrade a project from v3 to v4?

Run npx @tailwindcss/upgrade in a new branch. The tool needs Node.js 20 or higher and migrates dependencies, the configuration file and template changes, per the Tailwind upgrade guide.

Review the diff afterward, because renamed utilities such as shadow-sm becoming shadow-xs can change how a page looks.

Trying Tailwind CSS on One Small Project

Tailwind CSS proves its fit or loses it within one week on a single internal page, so keep the trial small and end it with a decision.

Start by building one internal page, where mistakes cost nothing. By day three, pull repeated class lists out into components. Before day five, review the markup as a team. The order matters, because each step exposes a different failure.

A Tailwind card makes a good first component, because card markup repeats and forces the extraction question early.

The team accepts one trade-off. Agreed rules for class order and extraction replace debates over class names.

This advice was verified in October 2026. The upgrade guide says Tailwind Labs is exploring a compatibility mode for older browsers, and its release would change the version decision for projects that can’t move to v4 today.

Bogdan Sandu
Latest posts by Bogdan Sandu (see all)