Migrate from Tailwind
Planning to migrate from Tailwind CSS to WovenUI? This guide maps Tailwind utilities and component classes to WovenUI core and the kit.
This page is for teams that style with Tailwind utilities and add a component layer on top, such as daisyUI, Flowbite, Tailwind UI or shadcn style components, and want ready-made HTML and CSS components on a token system. Utilities and components come from two packages: WovenUI core has the utility classes and apply() mixins, and @wovenui/components has the components. Install the kit from the install page. For the framework-level comparison, read WovenUI vs Tailwind CSS.
Utility mapping
Section titled “Utility mapping”In core the utility comes first and the modifier follows it: a breakpoint is a suffix (p-4@lg), a state is a prefix on the class (hover:bg-brand-subtle). Flex modifiers apply on a flex element, so write class="flex between x-center". The breakpoint names and sizes (md, lg) are core defaults, set by the $breakpoints setting; see the configuration page.
| Tailwind | WovenUI core | Notes |
|---|---|---|
flex justify-between |
flex between |
Main axis, no prefix |
items-center |
x-center |
x- is the cross axis |
items-start |
x-start |
On a flex element |
flex-col |
col |
On a flex element |
flex-1 |
grow |
On a child of a flex element |
shrink-0 |
no-shrink |
On a child of a flex element |
lg:p-4 |
p-4@lg |
Mobile first, from the breakpoint up |
md:flex-row |
row@md |
Same suffix for every utility |
hover:bg-blue-50 |
hover:bg-brand-subtle |
State prefix on the class; also hover:opacity-75, hover:shadow-md |
bg-white |
bg-surface |
Follows the theme |
text-gray-600 |
text-muted |
Semantic word, not a shade |
border-gray-200 |
border-regular |
Or plain border for the width |
ml-4, mr-4 |
ms-4, me-4 |
Logical, so they flip in right to left |
text-left |
text-start |
Logical |
z-50 |
z-modal |
Named levels |
space-x-4 |
space-x-4 |
Same name, logical |
dark:bg-gray-800 |
bg-surface |
No dark: class, see below |
top-[117px] |
top(117px) in SCSS |
Custom values live in SCSS |
Anything else with a state goes through apply(), for example bg(brand-hover) hover.
@apply becomes @include apply(...)
Section titled “@apply becomes @include apply(...)”Every utility is also a mixin. A Tailwind @apply line turns into one apply() call, with the modifier after the item:
@use "@wovenui/core" as *;
// Tailwind: @apply flex justify-between items-center p-4 bg-white rounded-lg hover:shadow-md lg:p-8;.toolbar { @include apply(flex, between, x-center, p(4), bg(surface), rounded(lg), shadow(md) hover, p(8) lg);}A unitless number is a scale key (p(4) is 1rem). A value with a unit is used as written (p(13px)). A wrong key stops the compile and the message lists the valid ones. Read more in Utility classes, apply(), Responsive and Flex.
Dark mode
Section titled “Dark mode”There are no dark: classes. Semantic classes such as bg-surface and text-muted read tokens, and the tokens switch with data-theme on any element:
<html data-theme="dark"> <body class="bg-base text-regular"> <aside data-theme="light" class="bg-surface p-4">A light panel in a dark page</aside> </body></html>Without data-theme the operating system decides. See Theming.
Component mapping
Section titled “Component mapping”Tailwind has no components of its own. The left column shows daisyUI markup, a common component layer; Flowbite and similar libraries use other class names for the same parts. The kit uses a wu- root and bare words for variants, valid only together with the root: wu-btn brand sm. Colors use the core role names, so primary becomes brand.
| daisyUI | WovenUI Components | Notes |
|---|---|---|
<button class="btn btn-primary"> |
<button class="wu-btn brand"> |
On a <button> or a link |
<button class="btn btn-error"> |
<button class="wu-btn danger"> |
Destructive actions |
<button class="btn"> |
<button class="wu-btn"> |
The plain button is the neutral one |
<button class="btn btn-outline"> |
<button class="wu-btn brand subtle"> |
A tinted outline; the plain wu-btn is outlined too |
<button class="btn btn-ghost"> |
<button class="wu-btn quiet"> |
Transparent until hover |
btn-sm, btn-lg |
sm, lg |
wu-btn brand sm |
<div class="badge badge-success"> |
<span class="wu-badge success"> |
Add solid for a filled badge |
<div class="card"> |
<article class="wu-card"> |
Parts: <header class="wu-card-header">, <div class="wu-card-body">, <footer class="wu-card-footer">; heading in wu-card-title |
<dialog class="modal"> |
<dialog class="wu-modal"> |
Opened with commandfor and command="show-modal", no script |
<div class="modal-action"> |
<form class="wu-modal-footer"> |
A <form method="dialog"> |
<details class="dropdown"> |
<div class="wu-dropdown" popover> |
Items are wu-dropdown-item links or buttons; opened with popovertarget, no script |
<div role="tablist" class="tabs"> |
<div class="wu-tabs"> |
Parts wu-tabs-list, wu-tabs-tab, wu-tabs-panel; active tab is aria-selected="true"; the kit script adds the keyboard |
<input type="checkbox" class="toggle"> |
<label class="wu-toggle"> |
Wraps <input class="wu-toggle-input" role="switch"> |
<input class="input"> |
<input class="wu-input"> |
On a text-like <input>; core already styles the border |
<select class="select"> |
<select class="wu-select"> |
On a native <select> |
<input type="checkbox" class="checkbox"> |
<label class="wu-checkbox"> |
Wraps <input class="wu-checkbox-input"> |
<input type="radio" class="radio"> |
<label class="wu-radio"> |
Wraps <input class="wu-radio-input">, like the checkbox |
<div role="alert" class="alert alert-success"> |
<div class="wu-alert success"> |
Title in wu-alert-title |
<div class="toast"> |
toast() from the kit script, or <div class="wu-toast"> |
Shown in a polite live region |
<table class="table table-zebra"> |
<table class="wu-table striped"> |
Also hover, bordered, sm |
<div class="drawer"> |
<dialog class="wu-drawer"> |
Inline end by default |
<div class="collapse"> |
<div class="wu-accordion"> |
Each item is <details class="wu-accordion-item">; no script |
<span class="loading loading-spinner"> |
<span class="wu-spinner"> |
Pair with role="status" and hidden text |
<progress class="progress"> |
<progress class="wu-progress"> |
On a native <progress> |
<div class="breadcrumbs"> |
<nav class="wu-breadcrumb"> |
Wraps <ol class="wu-breadcrumb-list"> |
<div class="tooltip" data-tip="..."> |
data-tooltip |
Lives in core, see tooltips |
Layout around the components still uses core utilities, so a card grid is grid and gap-4 from the first table, not a kit class.
Modals and dropdowns without JavaScript
Section titled “Modals and dropdowns without JavaScript”Tailwind gives you no modal or dropdown, so most teams add a script library or write the open and close code themselves. The kit gives you these without writing any JavaScript: a modal and drawer on <dialog>, a dropdown and popover on the popover attribute, and an accordion on <details>.
What differs on purpose
Section titled “What differs on purpose”- No class scanning. WovenUI does not read your source files to decide what CSS to generate. Utility classes are off by default in the Sass entry, so you ship tokens, base styles and the rules you write, and a component stylesheet adds only its own rules. The kit is compiled CSS: load the bundle, or per-component entries to load only what you use. See WovenUI vs Tailwind CSS for the details.
- Tokens and themes. Every component reads core
--wu-*tokens, so light, dark, inverse and high contrast need no extra classes and no per-colordark:pairs. - Native elements. Modals and drawers are
<dialog>, menus and popovers use thepopoverattribute, and accordions are<details>. The browser handles focus, Esc and the top layer, so most components need no JavaScript. - No icon set. The kit ships no icons. Markers such as the select arrow and the close cross are drawn in CSS. Bring the icon set you already use.
- Right to left. Components use logical properties, so one stylesheet serves both directions. See Right to left.
- Motion is opt-in. Components are calm by default. Add
animated(orwu-animatedon an ancestor) to turn motion on; it still respectsprefers-reduced-motion.
Migration checklist
Section titled “Migration checklist”- Install the kit. Load the bundle or per-component entries, not both.
- Replace layout and helper classes with core utilities, using the first table.
- Swap components one at a time with the component table. Keep the old CSS loaded until the last one is gone.
- Move colors and spacing to core tokens, and switch themes with
data-theme. - Remove the old framework’s CSS and script.
Next steps
Section titled “Next steps”- Install and download the kit.
- Read Right to left if you ship Arabic, Hebrew, Persian or Urdu.
- Compare the frameworks in WovenUI vs Tailwind CSS.
- Migrating from another library? See the guides for Bootstrap, Bulma, Foundation, Pico CSS, UnoCSS.