Compatibility

Purpose and Scope

Compatibility in Tailwind CSS has two related meanings. The first is user-facing platform compatibility: Tailwind CSS v4 is aimed at modern browsers, and the official documentation frames support around current Chrome, Safari, and Firefox releases. The second is code-level compatibility: the monorepo still exposes specific legacy-facing package entry points and compiler hooks so existing integrations, plugins, configuration files, and tooling can keep working while Tailwind’s primary model moves toward CSS-first configuration. This page connects those two ideas so application developers can decide which workflows are supported and integration authors can see where the compatibility surface lives in source.

The practical takeaway is that Tailwind is not trying to be a general replacement for every historical CSS toolchain. The official compatibility guidance describes Tailwind v4 as a full-featured CSS build tool rather than a plugin that should be nested inside Sass, Less, or Stylus workflows. In repository terms, that design appears in the core compiler entry point, which accepts CSS, resolves imports through loader callbacks, substitutes Tailwind functions and directives, tracks feature usage, and can optionally emit selected polyfills. Compatibility is therefore provided at the Tailwind boundary, not by preserving every behavior of every upstream preprocessor.

Sources: packages/tailwindcss/src/index.ts, packages/tailwindcss/package.json

Relevant Source Files

  • packages/tailwindcss/src/index.ts — Defines the public core compiler types used by integrations, including Config, CompileOptions, Features, Polyfills, CSS parsing, import substitution, and compatibility-hook imports.
  • packages/tailwindcss/package.json — Declares the published tailwindcss package exports, including CSS entry files and compatibility exports such as ./colors, ./defaultTheme, ./plugin, and ./lib/util/flattenColorPalette.
  • package.json — Shows repository-wide scripts and dependency posture for build, test, integration, UI, and package workflows that exercise compatibility across packages.
  • packages/@tailwindcss-browser/src/index.ts — Implements the browser runtime used by CDN-style workflows, including supported virtual imports, compiler creation, stylesheet observation, and browser-only import limitations.
  • packages/@tailwindcss-cli/src/index.ts — Provides the command-line compatibility surface for local builds, help output, build mode, and candidate canonicalization.
  • packages/@tailwindcss-node/src/index.ts — Exports the Node integration API and installs ESM cache hooks when available, with Bun and Node-version-aware behavior.

Browser and CSS Platform Compatibility

Tailwind CSS v4’s documented browser baseline is modern by design: Chrome 111, Safari 16.4, and Firefox 128 are the named core targets in the official compatibility page. That matters because Tailwind intentionally leans on platform features that older preprocessor-era stacks often attempted to abstract away. Native CSS variables, build-time CSS imports, modern selectors, and newer layout or interaction properties are treated as normal tools. Some utilities expose bleeding-edge platform features, so the compatibility decision sometimes shifts from whether Tailwind can compile a class to whether the browsers in your product support the resulting CSS property or at-rule.

The repository’s compiler surface reflects that platform-first posture. CompileOptions includes base, from, loadModule, and loadStylesheet, which makes the compiler responsible for loading Tailwind CSS, imported stylesheets, plugin modules, and config modules through integration-provided callbacks. The source also defines a Polyfills enum with AtProperty, ColorMix, and All, showing that Tailwind has explicit switches for selected generated fallbacks rather than a blanket promise to backport the whole CSS platform. When you choose a utility like scroll-smooth or an overscroll utility, Tailwind can generate the CSS, but browser support for the property remains a project compatibility decision.

Sources: packages/tailwindcss/src/index.ts

Compatibility Layer and Legacy Entry Points

The compatibility layer is visible from the top of the core package entry point: packages/tailwindcss/src/index.ts imports applyCompatibilityHooks, UserConfig, and the compatibility Plugin type. That means legacy JavaScript configuration and plugin concepts are still part of the compiler boundary, even though v4 documentation encourages CSS-first customization through directives, theme variables, and imports. The same file tracks Features.JsPluginCompat when @plugin or @config is used, alongside feature flags for @apply, @import, theme(...), utilities, variants, and @theme. These flags let integrations and tooling understand which compatibility-sensitive features participated in a compilation.

The package manifest makes the public compatibility contract more explicit. Besides the primary tailwindcss export and CSS files such as index.css, preflight.css, theme.css, and utilities.css, the package exports ./plugin, ./defaultTheme, ./colors, and ./lib/util/flattenColorPalette, including .js aliases for several of them. Those names preserve import paths that older Tailwind plugins and user code commonly depend on. In development exports they point at source files under src, while publishConfig.exports points at built dist files. For package consumers, the important detail is that these paths are intentionally declared package API, not accidental deep imports.

Sources: packages/tailwindcss/src/index.ts, packages/tailwindcss/package.json

Preprocessors, Imports, and CSS-First Workflow

The official compatibility docs are direct about Sass, Less, and Stylus: Tailwind v4 is not designed to be combined with them as a nested preprocessing step. The recommended mental model is to treat Tailwind itself as the build tool for Tailwind-authored CSS. That position lines up with the source: parsing begins from CSS AST nodes, substituteAtImports handles imports, substituteFunctions evaluates Tailwind CSS functions, and the compiler builds a design system from the parsed CSS. Instead of relying on postcss-import or a Sass import graph for Tailwind files, integrations provide loadStylesheet so Tailwind can bundle the CSS it understands.

A common compatibility-safe pattern is therefore to put Tailwind at the point where CSS is compiled, not upstream of another preprocessor. For example, an app stylesheet can import Tailwind and local CSS using normal CSS imports, then express customization with CSS variables and Tailwind directives. If your project still contains Sass for unrelated legacy styles, keep the boundary clear: compile or author those styles in a way that produces ordinary CSS before they interact with the Tailwind build, and avoid expecting Tailwind-specific directives to be evaluated by Sass. This reduces ambiguity around nesting, variables, import order, and plugin resolution.

Example CSS boundary:

@import "tailwindcss";
@import "./typography.css";
 
.typography {
  font-size: var(--text-base);
  color: var(--color-gray-700);
}

Sources: packages/tailwindcss/src/index.ts

Runtime and Tooling Compatibility

Compatibility is not only about generated CSS; it also depends on which runtime is hosting Tailwind. The browser package creates a compiler in the page, looks for style[type="text/tailwindcss"], injects @import "tailwindcss" when the user has not written an import, and compiles into an injected stylesheet. Its loadStylesheet function only recognizes the bundled Tailwind assets: tailwindcss, tailwindcss/preflight, tailwindcss/theme, tailwindcss/utilities, their .css variants, and local ./preflight.css, ./theme.css, and ./utilities.css aliases. Other imports throw an error in the browser build, which is an important compatibility constraint for CDN-style experiments.

The CLI and Node packages provide different compatibility surfaces for build tools and automation. The CLI entry point accepts root builds, an explicit build command, --help, and a canonicalize command for candidate lists; this preserves a simple executable path for projects that do not use Vite, PostCSS, or a framework integration. The Node package re-exports compile, optimization, dependency tracking, source-map, path-normalization, instrumentation, and environment helpers. It also accounts for runtime differences: Bun does not need the same module hook, while Node uses Module.registerHooks when present and falls back to Module.register for older supported APIs.

Sources: packages/@tailwindcss-browser/src/index.ts, packages/@tailwindcss-cli/src/index.ts, packages/@tailwindcss-node/src/index.ts

Compact Reference

AreaConcrete compatibility surfaceSource
Core compilerCompileOptions, Config, Features, Polyfills, loadModule, loadStylesheetpackages/tailwindcss/src/index.ts
Legacy plugin/config conceptsapplyCompatibilityHooks, UserConfig, compatibility Plugin, Features.JsPluginCompatpackages/tailwindcss/src/index.ts
Published compatibility importstailwindcss/plugin, tailwindcss/defaultTheme, tailwindcss/colors, tailwindcss/lib/util/flattenColorPalettepackages/tailwindcss/package.json
Published CSS importstailwindcss/index.css, tailwindcss/preflight.css, tailwindcss/theme.css, tailwindcss/utilities.css and extensionless aliasespackages/tailwindcss/package.json
Browser runtime importsVirtual tailwindcss assets and Tailwind CSS partials only; arbitrary browser @import values are rejectedpackages/@tailwindcss-browser/src/index.ts
CLI commandstailwindcss, tailwindcss build, tailwindcss canonicalize, --helppackages/@tailwindcss-cli/src/index.ts
Node runtimeRe-exported compile/optimize/source-map APIs plus Node/Bun-aware ESM cache hook setuppackages/@tailwindcss-node/src/index.ts

Operational Guidance and Next Steps

When evaluating compatibility for an application, start with the browser matrix and the CSS features you intend to use. Tailwind may expose utilities for modern properties such as smooth scrolling, overscroll behavior, field sizing, or balanced text wrapping, but the final behavior is governed by browser support for those properties. For older target browsers, prefer utilities backed by well-supported CSS or add your own progressive enhancement strategy. Treat Tailwind’s Polyfills switches as targeted compiler options for specific framework-generated patterns, not as a replacement for a full legacy-browser transformation pipeline.

When evaluating compatibility for tooling, prefer declared package exports and integration packages over deep imports. Use the tailwindcss package entry for core compilation, CSS imports for framework stylesheets, @tailwindcss/node for Node-based integrations, the CLI for direct command execution, and the browser package for Play CDN-style workflows. If you are maintaining older plugins or config-heavy projects, inspect the configuration and plugin API page next, because the compatibility hooks and published plugin, colors, defaultTheme, and flattenColorPalette exports are the pieces most relevant to migration. For workflow setup, continue to the installation, Vite, PostCSS, CLI, or browser-build pages depending on where Tailwind runs in your stack.

Sources: package.json, packages/tailwindcss/package.json, packages/@tailwindcss-node/src/index.ts