Resources · Craft & Compliance

Design systems & UI

Tailwind v4, DaisyUI, Lucide — and why this exact stack is the most AI-agent-friendly UI toolkit in 2026.

Picking a UI stack used to be a values war. Then Tailwind ate everything, and the question shifted from "which framework" to "which Tailwind layer." For an MVP being built with an AI coding agent, the answer matters more than it used to: agents read and modify the code you ship, and some styling approaches are vastly more legible to them than others.

This page walks through the realistic 2026 options for styling, components, and icons, then lands on what we actually run.

Tailwind v4 shipped in early 2025 and is the default starting point in 2026. The headline change versus v3 is that the engine is rewritten in Rust, configuration moved into CSS itself (no more tailwind.config.js for most projects), and the color system defaults to OKLCH — a perceptually uniform color space that gives you cleaner gradients, predictable dark-mode variants, and accurate hue rotation.

For an AI agent, Tailwind's appeal is concrete: utility classes like flex items-center gap-3 px-4 py-2 rounded-lg bg-primary text-primary-content describe layout and color in a single string the agent can edit without round-tripping through a stylesheet. There is no naming step, no "did you import the right CSS module," and no specificity ladder to debug.

/* app.css — the entire Tailwind v4 setup */
@import "tailwindcss";
@plugin "daisyui";

That's it. No PostCSS config, no separate config file, no plugin registration in JS.

Vanilla CSS modules

Still a valid choice if you have strong opinions about hand-written CSS or you're building a content-heavy site that doesn't benefit from utility-first thinking. The cost: every component invents new class names, agents have to grep for them, and dark mode is something you wire by hand. We don't recommend it for an agent-driven MVP.

Pico CSS (minimal alternative)

Pico is a class-light CSS framework that styles semantic HTML by default — write <button> and you get a styled button. It's tiny (~10 KB), beautiful out of the box, and a great pick for a one-page marketing site or a personal blog. It's a poor pick the moment you want a real design system, custom palette, or component variants.

Legacy options to skip

Framework Why not in 2026
Bootstrap 5 jQuery DNA, opinionated component look, hard to escape. Fine for internal tools, dated for new MVPs.
Bulma Pure-CSS, no JS, but the component vocabulary feels 2018 and the project is in maintenance mode.
Material-UI / MUI Heavy runtime, enforces Material Design aesthetic, theming is a wrestling match. Fine if you're cloning a Google product, otherwise no.

DaisyUI sits on top of Tailwind and gives you semantic component classes: btn, btn-primary, card, modal, input input-bordered. Under the hood they compile to Tailwind utilities, so you can override anything with regular utility classes in the same string.

For agent-driven work, this is the killer feature. When an agent reads <button class="btn btn-primary">Save</button> it understands the intent immediately. When it reads twenty utility classes, it has to reverse-engineer the intent every time. Semantic classes are also dramatically easier to refactor — change one DaisyUI theme variable and every button on the site updates.

DaisyUI 5 ships with ~35 themes, each defined as a small block of OKLCH colors in your CSS. Switching is a one-line attribute on <html>.

shadcn/ui

shadcn is the darling of the indie-React world: instead of installing a library, you copy components into your repo and own them. The tradeoff is real code surface — every component you use becomes 50–300 lines of JSX in your project. For a human team that wants total control, that's a feature. For an agent doing fast iteration, every additional file is more context the agent has to load and reason about.

We use shadcn when the design demands a specific custom interaction (e.g., a complex date range picker). For 95% of MVP UI, DaisyUI's pre-styled components ship faster.

Catalyst (Tailwind UI)

Tailwind Labs' official component set. Excellent quality, opinionated minimal aesthetic, paid ($299 one-time as of early 2026 for the full Tailwind UI catalog including Catalyst). Worth it if you're building a SaaS dashboard and want a pre-baked, professional look without design work. Skip it if budget matters or you want a more distinctive visual identity.

Radix Primitives

Headless, accessibility-first React primitives — dialogs, dropdowns, tabs, etc. Zero styling, you bring your own. shadcn/ui is built on Radix. If you're going custom, this is the unopinionated layer to build on. Not a substitute for DaisyUI; a complement to a hand-rolled component system.

Mantine

A full React component library (not Tailwind-based). 100+ components, very polished, dark mode built in, great form helpers. The tradeoff is another runtime, another theming system, and a styling approach (CSS-in-JS via emotion historically, now its own atomic CSS) that is not Tailwind. Fine choice — but it locks you out of the Tailwind/DaisyUI ecosystem.

Chakra UI (legacy)

Was a great pick around 2021–2023. The v3 rewrite is fine but the wider community has migrated to Tailwind-based stacks. New projects should not start here.

Stack comparison

Stack Setup time Bundle size AI-agent-friendly Customization A11y built in Dark mode
Tailwind v4 + DaisyUI 2 min ~30 KB CSS Excellent Excellent Good One attribute
Tailwind v4 + shadcn 10 min grows with use OK Total Excellent (Radix) Manual
Tailwind v4 only 1 min ~20 KB CSS Good Total None Manual
Mantine 5 min ~80 KB JS+CSS OK Excellent Excellent Built in
MUI 5 min ~120 KB JS+CSS Poor Painful Good Built in
Pico CSS 30 sec ~10 KB OK (limited surface) Limited Good Built in

Lucide is a community-maintained fork of Feather icons with around 1,500 icons and counting, all 24px, 2px stroke, perfectly consistent. The React package (lucide-react) tree-shakes per-icon, so importing twelve icons adds twelve icons' worth of bundle.

import { Search, Settings, ChevronRight } from "lucide-react";

<button className="btn btn-ghost btn-square">
  <Search className="h-5 w-5" />
</button>

The strokes are designed by the same person who designed Tailwind UI's official icons (Heroicons), so they pair cleanly with the Tailwind aesthetic.

Heroicons

Tailwind Labs' own set, ~300 icons, available in 24px outline, 24px solid, 20px solid, and 16px solid. Beautiful, narrow scope. If your product only needs the basics (chevron, x, check, search, plus), Heroicons is enough. If you have a content-heavy app with niche concepts, you'll hit the wall fast.

Tabler Icons

3,000+ icons, similar visual language to Lucide, broader coverage. Great pick when you need, say, a brand mark for an obscure file format or a specific medical icon. Slightly less curated than Lucide; you'll see some duplicates.

Phosphor Icons

Multiple weights (thin, light, regular, bold, fill, duotone) for the same icon. Fantastic for a polished marketing site where you want bold icons in hero sections and thin icons in dense UI. The cost is decision fatigue and a slightly larger bundle if you mix weights.

react-icons (avoid for new projects)

react-icons bundles dozens of icon sets behind a single import. It's convenient and a bundle-size disaster — the kitchen-sink convenience encourages mixing icon families, which is the single fastest way to make an interface look amateurish. Pick one icon family and stick to it.

Icon library comparison

Library Icon count Weights Visual style Bundle approach
Lucide ~1,500 1 Modern, consistent Tree-shaken per icon
Heroicons ~300 4 Clean, narrow Tree-shaken per icon
Tabler ~3,000 2 Modern, broad Tree-shaken per icon
Phosphor ~1,200 (per weight) 6 Geometric Tree-shaken per icon
react-icons 30,000+ (combined) varies Inconsistent Per-set, can be large

Why this combo for AI agents

Two patterns matter when an agent is the primary author:

  1. Semantic over atomic. btn btn-primary reads as "primary button" without parsing. Twelve utility classes read as "I have to compute what this is."
  2. Single-source theming. When the agent needs to change the brand color, editing one OKLCH value in app.css should propagate everywhere. DaisyUI themes do this; ad-hoc Tailwind doesn't unless you've been disciplined.

The result is less context burned per agent turn, fewer "wait, what is this component" sub-investigations, and faster iteration. We covered the broader information-architecture side of this in /blog/header-vs-footer/.

Our recommendation

Tailwind v4 + DaisyUI 5 + Lucide. This site runs that stack. The Vibe MVP starter ships with that stack pre-wired. If you're starting today and have no specific reason to deviate, copy that and move on to actual product work.

Concrete starting package.json deps:

{
  "dependencies": {
    "lucide-react": "^0.460.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  },
  "devDependencies": {
    "@tailwindcss/vite": "^4.0.0",
    "daisyui": "^5.0.0",
    "tailwindcss": "^4.0.0",
    "vite": "^6.0.0"
  }
}

Anti-patterns we keep seeing

  • Gradient buttons. Solid theme colors only. Gradients date a UI in months. The design skill in our skills bundle enforces this.
  • Body text under 16px. 14px feels "designy" and is a readability problem. 16px minimum on body, 14px floor for secondary metadata.
  • Header crammed with marketing nav. About, Pricing, Blog, Contact — those are footer links. Header is for the working surface only. Again, see /blog/header-vs-footer/.
  • Two icon libraries. Pick one. Mixing Heroicons outline with Lucide makes the UI look stitched together because the strokes don't match.
  • Custom-rolling a date picker / select / modal in week one. DaisyUI has all three. Use them, ship, replace later if a real product reason emerges.