NuvoUI vs Tailwind CSS
Both are utility-first. Tailwind is a CSS build tool that generates classes from your markup, including arbitrary values. NuvoUI is an SCSS framework: readable class names, the same utilities as apply() mixins, and theme tokens, compiled by Dart Sass alone.
Who should pick which
Pick Tailwind CSS if
- You want any value directly in markup: Tailwind generates arbitrary values such as
top-[117px]andbg-[#bada55]on the fly. - You want CSS generated from the classes you actually use, with no separate purge step: Tailwind scans your source files.
- You do not use Sass. Tailwind v4 is its own build tool and is not designed to be used with Sass, Less or Stylus.
- You want ready-made material: Tailwind Plus (a one-time purchase with components, templates and the Catalyst UI kit) and Headless UI (unstyled, accessible components for React and Vue).
- You want a mature project with official installation guides for many frameworks [9].
Pick NuvoUI if
- Your project already compiles Sass and you want no build plugin beyond Dart Sass.
- You prefer class names that read as words:
between,x-center,bg-surface,p-4@md. - You write component CSS and want every utility as a mixin:
@include apply(p(1.5rem), shadow(md) hover, p(8) lg). - You want semantic theme tokens out of the box:
bg-surfaceandtext-mutedfollow light, dark and inverse sections without adark:class per element. - You want mistakes caught at compile time: an unknown key such as
p(7)stops the build and lists the valid keys.
Side by side
| Topic | Tailwind CSS | NuvoUI |
|---|---|---|
| Philosophy | Utility-first: style elements by combining single-purpose utility classes directly in markup [1]. | Utility-first SCSS with human-readable names. Every utility class is also a mixin for apply(), so the same vocabulary works in HTML and in component stylesheets. |
| Syntax | Variants are prefixes: hover:bg-sky-700, md:uppercase (mobile-first, applies from the breakpoint up) [1][2]. | Breakpoints are suffixes, states are prefixes: p-8@lg, hover:shadow-md. In SCSS, modifiers follow the utility: apply(p(8) lg, shadow(md) hover). |
| Custom values | Arbitrary values in square brackets in markup, generated on the fly: top-[117px], bg-[#bada55] [3]. | No arbitrary values in class names. Custom values go through mixins: apply(top(117px), bg(#bada55)). A unitless number is a scale key; a value with a unit is used as written. |
| Customisation | CSS-first configuration with the @theme directive; theme variables decide which utility classes exist [4]. | Sass configuration in the first @use ... with (...): $brand, scale maps, theme override maps and feature flags, validated at compile time. |
| Theming and dark mode | dark: variant, based on prefers-color-scheme by default; a manual toggle is set up with @custom-variant [5]. Dark styles are written per utility unless you define your own semantic theme variables. | Semantic tokens switch with data-theme="light", "dark" or "inverse" on any element, with an operating system fallback. A [data-contrast="high"] hook applies $high-contrast-light and $high-contrast-dark override maps; both maps are empty by default. |
| RTL | rtl: and ltr: variants [6], and logical utilities such as ms-*, me-*, ps-*, pe-* [7][8]. | Logical utilities and mixins (ms, me, ps, pe, start-*, end-*, border-s, rounded-s-*, text-start) alongside physical ones. No rtl: variant; direction-specific overrides are written in SCSS. |
| Design tokens | Theme variables are also emitted as regular CSS variables, for example --color-mint-500 [4]. | --nu-* custom properties for surfaces, text, borders, focus, brand and status roles, the palette and every scale. Classes and mixins output var(--nu-*); token(name) raises an error for an unknown name. |
| Build requirements | Installed as a Vite plugin, a PostCSS plugin or the Tailwind CLI [9]. v4 targets Chrome 111, Safari 16.4 and Firefox 128 and later [10]. | Dart Sass 1.79 or later (below 2.0). No JavaScript, no runtime, no CLI and no PostCSS plugin. |
| Bundle approach | Scans source files as plain text and generates only the classes it finds. Class names built by string concatenation are not detected [11]. | No scanning. With $generate-utility-classes: true every configured class is emitted (about 1 MB minified, 93 KB gzipped with the defaults), so remove unused classes with a purge tool or switch feature flags off. Mixin-only use emits what you write plus about 43 KB of base CSS (tokens, reset, base elements, tooltips) per compiled entry. |
| JS components | None in the framework. Tailwind Plus is a paid, one-time purchase with components, templates and the Catalyst UI kit [12]; Headless UI provides unstyled, accessible React and Vue components, MIT licensed [13]. | None. Core is a foundation layer with no component library. It styles plain HTML buttons and form fields, and includes CSS-only tooltips. |
| Ecosystem | Official installation guides for Vite, PostCSS, the CLI and many frameworks [9], plus Tailwind Plus and Headless UI. | Small: the core package and its documentation. No plugin ecosystem or community templates. |
| Licence | MIT [14]. | MIT. |
The same component in both
A card with a title, text and an action, a hover shadow and more padding from the large breakpoint. The Tailwind version uses palette classes, so dark mode needs a dark: class for each colour. The NuvoUI version uses theme token classes (bg-surface, text-muted, border), so the same markup follows the theme.
<div class="flex flex-col gap-3 rounded-lg border border-gray-200 bg-white p-6
shadow-sm hover:shadow-md lg:p-8 dark:border-gray-700 dark:bg-gray-800">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Card title</h3>
<p class="text-gray-600 dark:text-gray-400">Some quick example text.</p>
<a href="#" class="self-start rounded-md bg-blue-600 px-4 py-2 text-white">Go somewhere</a>
</div><div class="flex col gap-3 p-6 p-8@lg bg-surface border rounded-lg
shadow-sm hover:shadow-md">
<h3 class="text-lg font-semibold">Card title</h3>
<p class="text-muted">Some quick example text.</p>
<a href="#" class="self-start px-4 py-2 rounded-md bg-brand text-on-brand">Go somewhere</a>
</div>@import "tailwindcss";
@theme {
--color-mint-500: oklch(0.72 0.11 178);
}@use "@nuvoui/core" as * with (
$brand: #4361ee
);
.card {
@include apply(
flex, col, gap(3),
p(6), bg(surface), rounded(lg), border(1),
shadow(md) hover, p(8) lg
);
}
.card__text {
@include apply(text-color(muted), mb(1.25rem));
}Moving from Tailwind CSS
- Rename layout classes:
flex-coliscol,justify-betweenisbetweenanditems-centerisx-center, each on a.flexelement. See Flex. - Move breakpoint prefixes to suffixes:
md:p-8becomesp-8@md. See Spacing and Media queries. - Replace arbitrary values in markup with a class from the configured scale, or with a mixin in SCSS:
@include apply(top(117px)). See apply(). - Replace
@themevariables with Sass configuration and theme override maps. See Configuration and Theming. - Replace
dark:class pairs with semantic token classes such asbg-surface,text-mutedandborder. See Tokens. - Look up any mixin or function in the A to Z reference.
Sources
Every statement about Tailwind CSS on this page comes from its official documentation or repository. Statements about NuvoUI come from the core source, its changelog and the core documentation.
- [1] Tailwind CSS: Styling with utility classeshttps://tailwindcss.com/docs/styling-with-utility-classes
- [2] Tailwind CSS: Responsive designhttps://tailwindcss.com/docs/responsive-design
- [3] Tailwind CSS: Adding custom styleshttps://tailwindcss.com/docs/adding-custom-styles
- [4] Tailwind CSS: Theme variableshttps://tailwindcss.com/docs/theme
- [5] Tailwind CSS: Dark modehttps://tailwindcss.com/docs/dark-mode
- [6] Tailwind CSS: Hover, focus and other stateshttps://tailwindcss.com/docs/hover-focus-and-other-states
- [7] Tailwind CSS: Marginhttps://tailwindcss.com/docs/margin
- [8] Tailwind CSS: Paddinghttps://tailwindcss.com/docs/padding
- [9] Tailwind CSS: Installing with Vitehttps://tailwindcss.com/docs/installation/using-vite
- [10] Tailwind CSS: Compatibilityhttps://tailwindcss.com/docs/compatibility
- [11] Tailwind CSS: Detecting classes in source fileshttps://tailwindcss.com/docs/detecting-classes-in-source-files
- [12] Tailwind CSS blog: Tailwind UI is now Tailwind Plushttps://tailwindcss.com/blog/tailwind-plus
- [13] Headless UI repositoryhttps://github.com/tailwindlabs/headlessui
- [14] Tailwind CSS repository (MIT licence)https://github.com/tailwindlabs/tailwindcss