Migration

From Tailwind UI

Nova extends the Tailwind mental model with type-safe, accessible primitives. You keep the class habit and drop the copy-paste maintenance.

Overview

Tailwind UI ships as HTML snippets. Nova ships composable React primitives styled with Tailwind v4. Migration is largely 1:1 — wrap regions in Nova components and delete the boilerplate classes they replace.

Install alongside

Add Nova without removing your current library. Migrate page-by-page.

tsx
bun add @novix-ui/react
# leave your existing Tailwind config as-is

Component mapping

FromNovaNotes
Custom <button> classesButtonVariants replace repeated class strings.
Icon <button> variantIconButtonEnforces aria-label at type level.
Card wrapper divsCardIncludes Moon-Edge highlight for free.
Custom Kbd spansKbd / KbdSequencePlatform-aware ⌘ vs Ctrl.
Loading placeholdersSkeletonShimmer + reduced-motion pulse.

Code diff

Before

tsx
<button class="inline-flex items-center gap-2 rounded-lg bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-400">
<svg .../>
Continue
</button>

After (Nova)

tsx
import { Button } from "@novix-ui/react";
import { ArrowRight } from "lucide-react";
 
<Button trailingIcon={<ArrowRight />}>Continue</Button>

Common traps

  • Tailwind UI's focus ring uses one layer. Nova ships a two-layer ring for contrast on any surface — don't override it.
  • Some Tailwind UI patterns nest links inside buttons; that's invalid HTML. Use Button's asChild to render onto a Link.
  • Tailwind UI grays are neutral-based; Nova's are OKLCH. Colors will shift subtly — recalibrate custom tokens in styles.css, not in components.