README.md
May 7, 2026 · View on GitHub
TailNG
Accessible Angular UI, built to be owned.
Angular 21+ components, headless primitives, theme contracts, and ownable source installs for teams building design systems and application UI.
What is TailNG?
TailNG is an open-source Angular UI system for applications and design systems that need accessible behavior, strict type safety, and implementation ownership.
The monorepo provides:
- Ready-to-use styled Angular components.
- Headless primitives for custom UI systems.
- Low-level accessibility, collection, overlay, and runtime utilities.
- Theme contracts, CSS variable tooling, and Tailwind adapters.
- A copy-source registry and CLI for shadcn-style local component ownership.
- Documentation and playground apps for package, Tailwind, plain CSS, and registry workflows.
TailNG is built with Angular 21+, standalone APIs, signals, Nx, Vitest, and strict ESLint boundaries.
Packages
| Package | Description |
|---|---|
@tailng-ui/components | Styled Angular components built on TailNG primitives. |
@tailng-ui/primitives | Headless, accessibility-first Angular primitives. |
@tailng-ui/cdk | Behavior, accessibility, collection, overlay, and runtime utilities. |
@tailng-ui/theme | Theme contracts, presets, CSS variables, component contracts, and Tailwind adapters. |
@tailng-ui/icons | Angular icon wrappers backed by @ng-icons. |
@tailng-ui/charts | Apache ECharts wrappers for Angular. |
@tailng-ui/registry | Metadata for ownable component installs. |
tailng | CLI for listing and copying ownable components into Angular apps. |
Installation
Install styled components:
pnpm add @tailng-ui/components @tailng-ui/primitives @tailng-ui/cdk
Install headless primitives:
pnpm add @tailng-ui/primitives @tailng-ui/cdk
Install the theme package:
pnpm add @tailng-ui/theme
Use the ownable-source CLI without adding it permanently:
pnpm dlx tailng list
pnpm dlx tailng add button
Primary peer dependencies:
@angular/core^21.1.0@angular/common^21.1.0@angular/forms^21.1.0@angular/platform-browser^21.1.0@angular/router^21.1.0tslib^2.3.0
Package-specific peer dependencies are listed in each package README.
Quick Example
import { Component } from '@angular/core';
import { TngButton } from '@tailng-ui/components';
@Component({
standalone: true,
imports: [TngButton],
template: `<tng-button tone="success">Continue</tng-button>`,
})
export class ExampleComponent {}
For headless usage:
import { Component } from '@angular/core';
import { TngPress } from '@tailng-ui/primitives';
@Component({
standalone: true,
imports: [TngPress],
template: `<button tngPress>Action</button>`,
})
export class ExampleComponent {}
Architecture
TailNG is organized as an Nx workspace with layered packages:
apps/
tailng-ui/
docs/ Documentation site
playground-plain-css/ Plain CSS playground
playground-registry/ Ownable install playground
playground-tailwind/ Tailwind playground
libs/
tailng/
cli/ tailng command-line tool
tailng-ui/
cdk/ Headless behavior and runtime utilities
primitives/ Headless Angular primitives
components/ Styled Angular components
theme/ Theme engine and CSS contracts
icons/ Icon wrappers
charts/ Chart wrappers
registry/ Ownable install metadata
Layering rules:
- Components depend on primitives and CDK contracts.
- Primitives depend on CDK behavior utilities.
- Styling is separated from behavior.
- Public APIs are exported from package entry points.
- Deep imports are avoided.
- Accessibility and keyboard behavior are treated as package contracts.
Product Direction
TailNG is moving toward a component platform that supports both package installs and source ownership.
Current priorities:
- Accessibility-first primitives and components.
- Wrapper abstractions that keep app usage simple.
- Component style contracts for slots, states, tokens, and hooks.
- No hard dependency on Tailwind or any single CSS framework.
- Copy-source installation through the
tailngCLI. - Stable package boundaries across CDK, primitives, components, theme, registry, and docs.
Development
Requirements:
- Node.js
>=20.20.0 - pnpm
>=10.30.0
Install dependencies:
pnpm install
Run the documentation site:
pnpm start:docs
Run playgrounds:
pnpm start:vanilla
pnpm start:tailwind
Build packages and apps:
pnpm run build
Build selected targets:
pnpm run build:docs
pnpm run build:theme
pnpm run build:cli
pnpm run build:vanilla
pnpm run build:tailwind
Build and publish docs locally (Cloudflare Pages):
CF_DOCS_PROJECT_NAME=taling-dev \
CLOUDFLARE_API_TOKEN=90Oh4-tjMr9Fxj8naoK_8odkfw8QdbHpS-CVNTf- \
CLOUDFLARE_ACCOUNT_ID=218f66f3a999f3f020117242ec252f18 \
./tools/build-deploy-docs.sh
Notes:
CF_DOCS_PROJECT_NAMEmaps to the Cloudflare Pages project name.CLOUDFLARE_API_TOKENandCLOUDFLARE_ACCOUNT_IDare required bywrangler.- If needed, you can override branch and output behavior with
CF_PAGES_BRANCHandDOCS_DIST.
Generate static output:
pnpm run seo:docs
pnpm run seo:vanilla
pnpm run seo:tailwind
If prerendering fails because Chrome is missing, install the browser once:
pnpm exec puppeteer browsers install chrome
Testing and Quality
Run all package tests:
pnpm run test:packages
Run the full Vitest suite:
pnpm run test:all
Run targeted tests:
pnpm run test:cdk
pnpm run test:primitives
pnpm run test:components
pnpm run test:theme
pnpm run test:icons
pnpm run test:charts
pnpm run test:registry
pnpm run test:cli
pnpm run test:docs
Lint and format:
pnpm run lint
pnpm run format:nx
pnpm run format:prettier
Typecheck key package surfaces:
pnpm run typecheck:registry
pnpm run typecheck:cli
pnpm run typecheck:docs
Run the ownable install contract checks:
pnpm run verify:ownable-contracts
TailNG CLI
Build and run the local CLI:
pnpm run build:cli
pnpm run run:tailng -- list
Preview generated files:
pnpm run run:tailng -- add button --cwd apps/tailng-ui/playground-registry --dry-run
Generate files:
pnpm run run:tailng -- add button --cwd apps/tailng-ui/playground-registry
Overwrite existing generated files:
pnpm run run:tailng -- add button --cwd apps/tailng-ui/playground-registry --force
tailng add <component-name> writes source under:
<cwd>/src/app/tailng-ui/<component>/
Import generated components from the local app path:
import { TngButton } from './tailng-ui/button';
Common aliases supported by tailng add:
| Alias | Canonical item |
|---|---|
slide-toggle | switch |
sidenav, sidebar, side-nav, sheet | drawer |
expansion-panel | accordion |
spinner | progress-spinner |
snackbar, sonner | toast |
Component Guidelines
- Use standalone Angular APIs.
- Prefer signals and
input()for component inputs. - Keep behavior and styling separate.
- Avoid default exports.
- Use explicit return types.
- Keep public APIs intentional and documented.
- Preserve accessibility semantics, roles, states, and keyboard behavior.
- Add or update tests when changing behavior.
Documentation
- Website: https://tailng.dev
- GitHub: https://github.com/tailng/tailng-ui
- npm components: @tailng-ui/components
- npm CLI: tailng
Contributing
Contributions are welcome.
Before submitting a PR:
- Run relevant tests and lint checks.
- Respect Nx boundaries and package layering.
- Avoid deep imports.
- Keep typing strict.
- Include docs or playground coverage for user-facing changes.
License
MIT © 2026 TailNG