Skip to content

0007. shadcn/ui on Tailwind CSS

  • Status: Accepted
  • Date: 2026-10-01

Context

The tenant web app and the admin portal are data-heavy business UIs: tables, forms, dialogs, menus, and dashboards. Both should share one look and one set of accessible components, and the team needs to adjust components freely without fighting a library's theming system.

Options considered

  1. A packaged component library (for example Ant Design or MUI): complete out of the box, but heavy, hard to restyle, and updates are all-or-nothing.
  2. Headless primitives only (Radix) with custom styling: full control, but every component must be built and styled from scratch.
  3. shadcn/ui: Radix-based accessible components copied into our own code and styled with Tailwind CSS, so we own and can change every component.

Decision

Use shadcn/ui with the Radix base, the Nova preset, and Lucide icons, on Tailwind CSS 4. Components live in the shared library libs/shared/ui and are used by both web and admin.

Consequences

  • Components are our code: easy to adapt, but updates from shadcn are pulled in deliberately with the CLI, not by bumping a version.
  • One theme (CSS variables in globals.css) styles both apps; dark mode and brand colours are a theme change.
  • Tailwind becomes the styling convention for all frontend code; CSS modules are not used for new components.
  • shadcn's alias-based self-imports require a narrow exception to the Nx self-import lint check in libs/shared/ui/src/components/ui/.