Primitives vs Full-Stack Components: What Your SaaS Actually Needs
The React ecosystem has a spectrum of component libraries. On one end: unstyled primitives (Radix, Ariakit, React Aria). On the other: full application kits with dashboards, auth flows, and marketing pages. In the middle: styled primitives like shadcn/ui and Mantine.
Most developers pick a library based on how it looks in a demo. The better question is: how much do you want to build yourself?
The Primitive Layer
Primitive libraries give you buttons, inputs, dialogs, dropdowns, tabs, tooltips, and accordions. They handle accessibility, keyboard navigation, and focus management. You handle everything else.
This is the right choice when:
- You have a design team building a custom design system
- Your product has unique interaction patterns
- You want full control over every visual decision
- Development time isn't a constraint
The trade-off: you build everything above the primitive layer yourself. Sidebar layout. Data table with sort/filter/paginate. Settings pages. Auth forms. Marketing sections. Stats cards. Empty states.
That's weeks of work. Each piece isn't hard individually, but there are dozens of them.
The Application Layer
Application-level component libraries ship the patterns that sit above primitives:
| Pattern | Time to build from scratch |
|---|---|
| Dashboard shell with responsive sidebar | 2-3 days |
| Data table with sorting, filtering, pagination | 2-3 days |
| Auth flow (login, signup, forgot password) | 1-2 days |
| Settings pages (profile, billing, API keys) | 2-3 days |
| Marketing sections (hero, pricing, testimonials) | 2-3 days |
| Onboarding wizard | 1-2 days |
| Email templates | 1 day |
Total: 2-3 weeks of focused development to reach the starting line. And that's for a developer who's built these patterns before.
Application kits give you these pre-built, integrated, and consistent. The value isn't in the individual component — it's in the fact that 30 components share the same design tokens, the same TypeScript patterns, and the same dark mode implementation.
The Integration Tax
The hidden cost of building from scratch isn't any single component. It's making them work together.
Your data table needs to match your sidebar's typography. Your auth forms need to use the same input styles as your settings pages. Your marketing hero needs to share color tokens with your dashboard charts.
With primitives, you design this consistency yourself. With an application kit, it's a given.
Evaluating a Component Kit
Whether free or paid, check for:
Design system, not just components — Does it use a token system (CSS variables) for colors, spacing, and typography? Or are styles hardcoded? Token systems mean you can rebrand. Hardcoded styles mean you're married to their aesthetic.
Framework match — Is it built for your stack? A component kit designed for Next.js App Router with server components is fundamentally different from one designed for Vite SPAs. Generic kits require adaptation. Framework-matched kits don't.
Source ownership — Do you get the source code or a dependency? Packaged components (npm) lock you to their API. Copied components (CLI install) give you full ownership.
Dark mode as a system — Does dark mode work out of the box, or do you need to add dark: variants to every element? Good kits use CSS variables that swap automatically.
TypeScript coverage — Are props typed? Are exports documented? Can your IDE autocomplete everything? Untyped components are a productivity drain.
When to Use What
Start with primitives when:
- You're building a design system for a large team
- Your product needs non-standard interaction patterns
- You have designers who will specify every component
- Time to market isn't critical
Start with an application kit when:
- You're shipping a SaaS and need to move fast
- You're a solo developer or small team
- You need dashboard, auth, settings, and marketing out of the box
- You'd rather customize existing components than build from zero
Use both when:
- Your kit covers 80% of your needs and you build the remaining 20% on primitives
- You want consistency for standard patterns and flexibility for custom ones
The question isn't which approach is better. It's which matches your constraints. A solo founder with a launch deadline and a 20-person design team with a multi-quarter roadmap need fundamentally different tools.