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 (recommended)
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 5 (recommended component layer)
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 (recommended icon library)
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:
- Semantic over atomic.
btn btn-primaryreads as "primary button" without parsing. Twelve utility classes read as "I have to compute what this is." - Single-source theming. When the agent needs to change the brand color, editing one OKLCH value in
app.cssshould 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.
Related reading
- /blog/header-vs-footer/ — IA principle behind our nav choices
- /blog/wcag-22-aa-afternoon/ — accessibility checks that pair with this stack
- /blog/playwright-visual-review/ — how we catch UI regressions
- /resources/dev-tools/ — the agents that write the JSX
- /skills/ — the design skill in the bundle that enforces these rules