Skip to content

Compatibility & Upgrading

This page collects what you need to know before upgrading or relying on exact output: the runtime requirements, which TailwindCSS release the port follows, where TailwindPHP knowingly differs from TailwindCSS, and the notes for each release. The full history is in CHANGELOG.md.

Requirements

  • PHP 8.2 or later. The test suite runs on PHP 8.2, 8.3, and 8.4.
  • The ctype and mbstring extensions. The compiler calls ctype_* and mb_chr(). Both ship with most PHP builds and with the official Docker images, but composer.json does not declare them yet (#11), so a build without them installs the package and fails at runtime.
  • Optional: pcntl lets the CLI's --watch mode stop cleanly on SIGINT/SIGTERM. Without it, watch mode still works.

No Node.js, no FFI, and no native binaries are involved.

Which TailwindCSS release is tracked

Release 1.7.0 tracks TailwindCSS v4.3.3. The upstream repository is pinned as a git submodule in reference/tailwindcss, its test suites are extracted from that pinned checkout, and the 4,427 tests run on every push (see Performance & testing). The ported plugins follow @tailwindcss/typography and @tailwindcss/forms, and the class utilities follow clsx, tailwind-merge, and CVA, each pinned the same way.

Known differences from TailwindCSS

Serialization details

Generated CSS matches the reference test suites. A few serialization details differ from what the TailwindCSS CLI prints, none of which changes the cascade:

  • Vendor prefixes: where the reference emits both the authored -webkit-* line and a generated one, TailwindPHP emits one line.
  • Downleveled pseudo-elements (::file-selector-button, ::-webkit-datetime-edit-*) stay in their authored selector lists instead of being split into one rule per pseudo-element.
  • Authored single-quoted strings stay single-quoted ('Segoe UI') instead of being normalized to double quotes.
  • Co-occurring longhands are not combined into a shorthand (Tailwind's own output never needs it).
  • .p-0 keeps padding: 0px where the reference CLI emits padding: 0, because the extracted test corpus pins the 0px form. The minifier shortens it to 0.

Not included

TailwindPHP is a CSS compiler. It leaves out the editor tooling of the Tailwind ecosystem (IntelliSense, autocomplete, class sorting) and source maps, so the CLI has no --map option.

Content scanning

tw::generate() and TailwindCompiler::generate() read class names from class and className attributes only. For class names held in PHP or JavaScript strings, use tw::extractCandidatesFromStrings() or @source inline("…"). Path forms of @source are ignored by the API and only partly honoured by the CLI (see below).

Known issues in the current release

Area Behavior today Issue
CLI @source Paths and globs are not applied; the input file's directory is scanned instead, and @source not excludes nothing. See What the CLI scans #8
CLI --optimize Minifies, like --minify #9
CLI long options --input file.css (space-separated) is ignored; use --input=file.css or -i file.css #13
Plugin variants addVariant()/matchVariant() variants and the typography element modifiers (prose-headings: …) compile without their selector #10
@apply mixins @apply --my-mixin; is dropped instead of passed through #12
Reference imports Output is empty when a reference import precedes the utilities import; @import "tailwindcss" reference has no effect #14

Upgrade notes

1.7.0

  • Output changes byte-wise compared with 1.6.x, while staying functionally equivalent to the TailwindCSS v4.3.3 reference. Among the visible changes:
    • Spacing multipliers: p-1 emits padding: var(--spacing) instead of a calc(), and a multiplier of 0 emits a plain zero length.
    • Fractions fold to percentages: w-1/2 emits width: 50%.
    • Colors: oklch()/oklab() lightness serializes as a percentage (oklch(62.3% .214 259.815)), white and black shorten to #fff and #000.
    • The CSS2 pseudo-elements serialize with a single colon (:before, :after, :first-letter, :first-line).
    • Nested @media/@supports/@container rules flatten in place, in source order, instead of being hoisted to the end; declarations are reordered the way lightningcss orders them; shadowed duplicate declarations are removed.
  • Caches keyed on output bust once. The file cache of tw::generate() does not include the TailwindPHP version in its key, so run tw::clearCache() (or the directory you passed as cache) after upgrading. The compiler state cache invalidates itself.
  • New: @variant in author CSS, CSS mixins in @apply, @media reference and @import "…" reference, the full --value()/--modifier() engine for functional @utility, stricter @utility name validation, and the polyfills option of tw::compile().

1.6.1

  • New: the container utility (width: 100% plus one max-width per breakpoint).
  • Composed --tw-* variables (translate, scale, rotate, skew, filters, and others) are now registered with @property, so stylesheets gain those @property rules and transforms such as translate-x-7 take effect in the browser.

1.6.0

  • New: the persistent compiler state cache (stateCacheFile on tw::compile() and TailwindCompiler, StateCache\compileCssCached()), and the split parseCssState()/finalizeCssState()/compileParsed() functions. Existing calls behave exactly as before.

1.5.0

  • Subclasses of TailwindCompiler that override generate() or css() must add the optional bool $minify = false parameter; PHP rejects overrides that drop a parent's optional parameter.
  • Minified output comes from the serializer, so minified bytes differ slightly from 1.4.x (caches keyed on minified output bust once).
  • New: generateExact() and cssExact() for per-page CSS from one long-lived compiler.