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
ctypeandmbstringextensions. The compiler callsctype_*andmb_chr(). Both ship with most PHP builds and with the official Docker images, butcomposer.jsondoes not declare them yet (#11), so a build without them installs the package and fails at runtime. - Optional:
pcntllets the CLI's--watchmode stop cleanly onSIGINT/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-0keepspadding: 0pxwhere the reference CLI emitspadding: 0, because the extracted test corpus pins the0pxform. The minifier shortens it to0.
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-1emitspadding: var(--spacing)instead of acalc(), and a multiplier of0emits a plain zero length. - Fractions fold to percentages:
w-1/2emitswidth: 50%. - Colors:
oklch()/oklab()lightness serializes as a percentage (oklch(62.3% .214 259.815)),whiteandblackshorten to#fffand#000. - The CSS2 pseudo-elements serialize with a single colon (
:before,:after,:first-letter,:first-line). - Nested
@media/@supports/@containerrules 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.
- Spacing multipliers:
- Caches keyed on output bust once. The file cache of
tw::generate()does not include the TailwindPHP version in its key, so runtw::clearCache()(or the directory you passed ascache) after upgrading. The compiler state cache invalidates itself. - New:
@variantin author CSS, CSS mixins in@apply,@media referenceand@import "…" reference, the full--value()/--modifier()engine for functional@utility, stricter@utilityname validation, and thepolyfillsoption oftw::compile().
1.6.1
- New: the
containerutility (width: 100%plus onemax-widthper breakpoint). - Composed
--tw-*variables (translate, scale, rotate, skew, filters, and others) are now registered with@property, so stylesheets gain those@propertyrules and transforms such astranslate-x-7take effect in the browser.
1.6.0
- New: the persistent compiler state cache (
stateCacheFileontw::compile()andTailwindCompiler,StateCache\compileCssCached()), and the splitparseCssState()/finalizeCssState()/compileParsed()functions. Existing calls behave exactly as before.
1.5.0
- Subclasses of
TailwindCompilerthat overridegenerate()orcss()must add the optionalbool $minify = falseparameter; 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()andcssExact()for per-page CSS from one long-lived compiler.