Stillwind supports the utilities, variants, theme, CSS directives, and plugins of Tailwind CSS v4. To move a project, follow Migrating from Tailwind CSS. This page lists what works, how Stillwind checks it, and where Stillwind differs.
What works
| Tailwind feature | Support |
|---|---|
| Default theme and preflight | Included in @import "stillwind" |
| Utilities and variants | Supported, including arbitrary values, modifiers, and ! |
@theme, @utility, @custom-variant |
Supported |
@apply, @variant |
Supported |
--theme(), --spacing(), --alpha() |
Supported |
theme(--color-red-500) |
Supported; v3 paths such as theme(colors.red.500) are not |
@plugin with JavaScript plugins |
Supported; see Plugins and CSS packages |
@import of CSS packages |
Supported; see Plugins and CSS packages |
| Tailwind configuration | Set the tailwind field of the project in stillwind.config.ts |
How Stillwind checks compatibility
The test suite compares Stillwind with the Tailwind compiler. It runs both compilers on the same input and fails when their results differ:
- For utilities and variants, it compares the generated CSS for each class in Tailwind’s public class list and in its variant list.
- For plugins and CSS packages, it builds the same stylesheet with both compilers and compares the computed styles in Chrome.
The declarations inside a rule can stand in a different order from Tailwind’s, as CSS ordering describes. The order of two declarations that can affect each other stays the same, so the computed styles do not change.
Plugins and CSS packages
Tailwind CSS v4 plugins work in Stillwind in principle. The test suite runs the following packages in Vite development and production builds and in Rspack production builds. It also compares their output with Tailwind.
Load these packages with @plugin:
| Package | Example |
|---|---|
@tailwindcss/typography |
prose, prose-lg, prose-headings: |
@tailwindcss/forms |
form-input, and the base styles of forms |
daisyui |
btn, card, badge, themes |
tailwindcss-animate |
animate-in, fade-in-50 |
tailwindcss-motion |
motion-preset-fade, motion-duration-700 |
tailwind-scrollbar |
scrollbar-thin, scrollbar-thumb-brand |
tailwindcss-radix |
radix-state-open: |
tailwindcss-react-aria-components |
selected: |
@headlessui/tailwindcss |
ui-open: |
@iconify/tailwind4 |
icon-[lucide--home] |
For Iconify icons, Stillwind also provides the
@stillwind/plugin-iconify plugin.
Load these packages with @import:
| Package | Example |
|---|---|
tw-animate-css |
animate-in, fade-in-50 |
tailwindcss-animated |
animate-fade, animate-duration-700 |
tailwindcss-intersect |
intersect: |
tailwindcss-safe-area |
pt-safe-or-4 |
tailwind-scrollbar-hide/v4 |
scrollbar-hide |
preline/variants.css |
hs-dropdown-open: |
Other plugins can use the same features. @plugin
lists the supported plugin API. JavaScript plugins need the tailwindcss package,
and CSS packages do not.
The tests cover CSS. They do not run the JavaScript of a package, such as the components of Preline. Plugins have no browser test with webpack or Next.js. Test these combinations in your application.
Class names that a plugin’s selectors use
A plugin can select an element by a fixed class name. For example, the rules of
prose skip elements inside not-prose. style() keeps such a class in the
class attribute, so style("not-prose") adds the class not-prose. The class
keeps its name only without variants, so
invalid-marker-use reports hover:not-prose.
What Stillwind does not support
These differences come from the design of Stillwind. No setting changes them.
Classes outside style()
Only style() calls generate utilities. Stillwind does not scan files, so these
features have no replacement:
@source,@source inline(), andsource(...)on@import- A safelist of class names
- Tailwind classes inside a dependency
- Utility classes that JavaScript adds at runtime, such as
`bg-${color}-600`
Write each utility that you need in a style() call in your own code. For HTML
that you do not control, see
Avoid separate CSS.
The tw: class prefix
Stillwind generates unique class names, so utilities do not need a prefix. Write
p-4 instead of tw:p-4. Theme variables can still collide with other CSS in the
page. To prefix them, set themePrefix on the project, as
Migrating from Tailwind CSS
describes. In a plugin, prefix() returns the class name unchanged.
Other differences
| Tailwind | Stillwind |
|---|---|
@reference |
Ignored; @import the stylesheet from the stylesheet of the project |
theme(colors.red.500) |
Stays in the CSS, where browsers reject it; use --theme(--color-red-500) |
blocklist |
Has no effect; use the no-restricted-utilities lint rule |
| Utilities that generate invalid CSS | Rejected, such as justify-baseline, because justify-content has no such value |
addVariant() with the v3 :merge() form |
Skipped, as in Tailwind CSS v4 |
ignored-tailwind-feature reports the features in your stylesheet that have no effect.