Getting started
Install the core package, point Tailwind at the component sources, and add the components you need. Five minutes, and one thing that catches almost everyone — the @source glob.
Requirements
- Angular 22
- Tailwind CSS 4
@angular/cdk22 — a peer dependency of most packages, installed for you byng add
Install
The schematic installs @xui/core and patches your global stylesheet: the theme import, the CDK overlay stylesheet, and a @source glob that lets Tailwind see the classes inside the published packages. It is idempotent — run it twice and it only adds what is missing.
ng add @xui/coreThen add the components you need:
pnpm add @xui/button @xui/dialog @xui/iconNx workspace?
nx add @xui/core instead — it resolves the schematic through the Nx executor. Pass --skip-overlay if you will not use dialogs, drawers, popovers, tooltips, menus or toasts. Wiring it by hand
If you would rather not run the schematic, this is everything it writes into your global stylesheet:
@import 'tailwindcss';
/* The design tokens every @xui/* package styles against. */
@import '@xui/core/styles/theme.css';
/* Only needed for an overlay surface — popover, tooltip, menu,
dialog, drawer or toast. */
@import '@angular/cdk/overlay-prebuilt.css';
/* Tailwind only emits utilities it can see, and it does not scan
node_modules by default. */
@source '../node_modules/@xui'; The @source line is the one that matters. Tailwind 4 only emits a utility it has seen in a scanned file, and it does not scan node_modules by default — without it every component renders unstyled. The path is relative to the stylesheet, so adjust the ../ segments to match where yours lives.
Your first component
import { Component } from '@angular/core';
import { XuiButtonImports } from '@xui/button';
import { XuiCalloutImports } from '@xui/callout';
@Component({
selector: 'app-example',
imports: [XuiButtonImports, XuiCalloutImports],
template: `
<xui-callout color="warning" title="Unsaved changes">
Leaving now discards your edits.
</xui-callout>
<div class="mt-4 flex gap-2">
<button xuiButton color="primary">Save</button>
<button xuiButton variant="outline">Discard</button>
</div>
`
})
export class Example {}The imports barrel
Every package exports a Xui<Name>Imports const holding each declarable it ships — the component, its directives, its content projections. Import the barrel rather than the individual classes and a template cannot fail for a missing directive you did not know about.
import { XuiSelectImports } from '@xui/select';
@Component({
imports: [XuiSelectImports],
// <xui-select>, <xui-option>, <xui-option-group> — all of them
})The class input
Every component takes a class input and merges it with its own classes through tailwind-merge. A conflicting utility replaces the component's instead of fighting it, so there is no specificity war and no !important.
<!-- layout is yours -->
<xui-select class="w-64" />
<div xuiCard class="max-w-sm">…</div>
<!-- appearance is the component's -->
<button xuiButton color="error" variant="outline" size="sm">Delete</button> Reach for class for layout — width, placement, spacing between siblings. For anything visual, check whether the component has a variant input first; it almost always does.
Overlays
Popovers, tooltips, menus, dialogs, drawers and toasts render through the CDK overlay container, which owns stacking. Never set z-index on one by hand. If an overlay appears inline in the page instead of floating, the overlay stylesheet import is missing.
@import '@angular/cdk/overlay-prebuilt.css';Right-to-left
Components read direction through @angular/cdk/bidi, which walks up to the nearest dir attribute. Set it on <html> and the whole library flips — component templates use logical properties (ms-, pe-, start-) rather than left and right, so your own markup needs no changes either.
<html dir="rtl">Troubleshooting
Everything renders unstyled
Tailwind is not scanning the packages. Check the @source path resolves from your stylesheet to node_modules/@xui.
An overlay renders in the page flow
The CDK overlay stylesheet is missing. Add the @angular/cdk/overlay-prebuilt.css import.
Colours look right in one theme and wrong in the other
A raw palette class crept in — bg-white, text-zinc-900. Those cannot follow the active theme. See Theming for the semantic token that replaces it.
A directive in a template does nothing
A declarable is missing from imports. Use the package's Xui<Name>Imports barrel rather than naming classes individually.