@ng-zen/cli
v22.9.0
Published
Angular CLI generator for creating fully customizable UI components.
Maintainers
Keywords
Readme
🚀 Getting Started
The fastest way to install the CLI and generate your first component.
1. Add the package to your Angular 20+ project:
ng add @ng-zen/cli2. Generate UI components (interactive mode):
ng generate @ng-zen/cli:ui3. Generate layouts (interactive mode):
ng generate @ng-zen/cli:layouts4. Use the generated standalone component:
import { ZenButton } from './ui/button';
@Component({
imports: [ZenButton],
template: `
<button variant="primary" zen-button>Action</button>
`,
})
export class MyComponent {}Table of Contents
- Getting Started
- Features
- CLI Usage & Options
- Available UIs
- Available Layouts
- Customization
- ESLint Configuration
- Philosophy & Architecture
- Community & Contributions
- Documentation & Links
✨ Features
- Signal First Architecture: Designed natively for Angular's reactive model. Full support for Signal Inputs, Queries, Model signals, and the new Signal Forms API.
- Own Your Code: Components are generated as raw
.ts,.html, and.scssfiles directly in your project. You control the implementation. - Agnostic Styling: Built with raw SCSS and CSS Variables. No forced dependencies on Tailwind CSS, but fully adaptable if needed.
- Modern Angular: Leverages Standalone Components, OnPush change detection, and eliminates unnecessary RxJS overhead in UI layers.
- Production Ready: Includes Vitest unit tests, Storybook stories, and accessibility features out of the box.
🛠️ CLI Usage & Options
Generate multiple components at once, specify custom paths, or include Storybook documentation files directly from the terminal.
ng generate @ng-zen/cli:ui [path] --ui <elements...> --storiesArguments & Flags
| Property | Status | Default | Description |
| :-------------- | :--------- | :------------ | :--------------------------------------------------------------------------------------------------------------------------- |
| [path] | Optional | src/app/ui | The directory where components will be generated (e.g., ./src/app/shared/components). |
| --ui | Required | - | A space-separated list of components to generate (e.g., button, alert, dialog). Interactive prompt appears if omitted. |
| --stories | Optional | false | Generates .stories.ts files alongside the component, instantly ready for your Storybook integration. |
| --project | Optional | auto-detected | Specify the target project name in a multi-project workspace. |
Examples
Interactive mode (Recommended):
ng generate @ng-zen/cli:uiGenerate specific components to a custom path:
ng generate @ng-zen/cli:ui ./src/app/shared/components --ui avatar badge cardGenerate components with Storybook files:
ng generate @ng-zen/cli:ui --ui button input --storiesLayouts
Generate app-shell layouts (page-level components composed with UI components) into src/app/layouts by default.
ng generate @ng-zen/cli:layouts [path] --layouts <elements...> --stories| Property | Status | Default | Description |
| :-------------- | :--------- | :---------------- | :-------------------------------------------------------------------------------------------------------- |
| [path] | Optional | src/app/layouts | The directory where layouts will be generated (e.g., ./src/app/shared/layouts). |
| --layouts | Required | - | A space-separated list of layouts to generate (e.g., dashboard). Interactive prompt appears if omitted. |
| --stories | Optional | false | Generates .stories.ts files alongside the layout, instantly ready for your Storybook integration. |
| --project | Optional | auto-detected | Specify the target project name in a multi-project workspace. |
Generate the dashboard layout with Storybook files:
ng generate @ng-zen/cli:layouts --layouts dashboard --storiesLayout stories compose generated UI components (dashboard stories use
sidenav,buttonandicon). Generate those UI components at their default paths first so the story imports resolve.
🧩 Available UIs
Forms & Inputs
| Component | Description | Features | | ---------------- | --------------------- | ---------------------------------------------------------------- | | Checkbox | Form checkboxes | Indeterminate state, custom styling, validation | | Form Control | Form field wrapper | Labels, validation messages, required indicators | | Input | Text input fields | Validation states, prefixes/suffixes, types | | Radio | Form radio buttons | Group selection, two-way binding, custom styling, disabled state | | Switch | Toggle controls | On/off states, disabled state, custom labels | | Textarea | Multi-line text input | Auto-resize, character counts, validation |
Data Display
| Component | Description | Features | | ----------- | -------------------------------- | ------------------------------------------------------------------------------ | | Avatar | User profile images and initials | Image fallback, size variants, rounded styles | | Badge | Status indicators and labels | 6 variants, icons support, focus-visible ring | | Card | Content container | Multi-slot projection (header, title, subtitle, footer), CSS custom properties | | Divider | Visual separators | Horizontal/vertical, with labels, custom thickness | | Icon | SVG icon system | Built to support any SVG icon library. Size variants, colors |
Feedback
| Component | Description | Features | | ------------ | ---------------------- | ---------------------------------------- | | Alert | Informational messages | Customizable styles, dismissible options | | Skeleton | Loading placeholders | Multiple shapes, animation, responsive |
Actions & Overlays
| Component | Description | Features | | ----------- | ---------------------------- | ------------------------------------------------------------------------- | | Button | Interactive buttons | Primary/secondary variants, loading states, icons | | Dialog | Native modal dialogs | Native dialog element, service API, size variants, backdrop config | | Drawer | Side-sheet overlays | Native dialog element, swipe-to-dismiss, 4 sides, size variants | | Pin | Anchor-positioned overlay | CSS Anchor Positioning, TemplateRef content, position and offset controls | | Popover | Native Popover API directive | Template/string content, placements, click toggle, CSS anchor positioning |
Navigation
| Component | Description | Features | | ----------- | --------------------------- | ---------------------------------------------------------------- | | Sidenav | Responsive navigation shell | Collapsible rail, mobile bottom bar, header/content/footer slots |
🧭 Available Layouts
| Layout | Description | Features |
| ------------- | --------------------------------------------- | ------------------------------------------------------------------------------ |
| Dashboard | Responsive app shell: nav + content | Nav slot + scrollable main, in-flow mobile bottom bar, pairs with sidenav |
| Focus | Centered shell for screens outside app chrome | Pure centered slot, safe overflow scroll, max-width container, auth/onboarding |
🎨 Customization
Every generated component utilizes CSS variables for immediate theming without touching the core logic. Overwrite them globally or locally:
/* styles.scss */
:root {
/* Global theme variables */
--zen-primary: hsl(221deg 83% 53%);
--zen-transition-duration: 0.3s;
--zen-outline: 2px solid hsl(221deg 83% 53% / 50%);
/* Component-specific overrides */
--zen-button-primary: hsl(221deg 83% 40%);
--zen-button-shadow: 0 4px 6px hsl(0deg 0% 0% / 15%);
}For structural changes (e.g., modifying the default 0.625rem border radius or internal padding), simply edit the generated .scss files in your ./ui directory.
🔧 ESLint Configuration
ng-zen provides a flat ESLint config for UI components and generated files.
Auto-setup during ng add:
ng add @ng-zen/cli
# → Prompt: "ESLint config detected. Update it for ng-zen UI components?"It adds @ng-zen/cli/eslint-config to your eslint.config.* and spreads it into the defineConfig array. This enforces the zen prefix on component selectors and relaxes rules for .stories.ts / .spec.ts files generated inside ui/ and layouts/ directories.
Manual setup (if you declined the prompt):
import ngZen from '@ng-zen/cli/eslint-config';
export default defineConfig([...otherConfigs, ...ngZen]);Custom path or rules — use the named exports for fine-grained control (use layoutsFiles the same way for generated layouts):
import ngZen from '@ng-zen/cli/eslint-config';
export default defineConfig([
ngZen.createNgZenConfig({ uiFiles: 'src/app/shared/components' }),
...ngZen.generatedFiles,
]);🏛️ Philosophy & Architecture
Perfect For
- Enterprise Teams: Build consistent internal design systems without vendor lock-in.
- Startup Projects: Rapid prototyping with components that can be easily customized as requirements scale.
- Angular Developers: Maintain full control over component behavior while enforcing modern Angular patterns (Signals, Signal Forms, Standalone).
Advanced Details
- Zero Configuration: Works seamlessly with standard Angular CLI workspaces.
- Reactive by Design: Built from the ground up to utilize Angular Signals for state management, making integration with modern state libraries and Signal Forms seamless.
- Continuous Updates: Updating
@ng-zen/clibrings new features and component blueprints, but will never overwrite or break your already generated code. - Icon Agnostic: The optional
zen-iconis built to be completely library-agnostic. While@hugeicons/core-free-iconsis used in examples, you can integrate it with any SVG icon provider.
🤝 Community & Contributions
Built by developers, for developers.
This project is actively developed and shaped by community feedback. We are highly open to suggestions, new features, and improvements.
- Missing a component? Open a feature request.
- Found a bug? Submit an issue.
- Have an idea? Start a discussion.
We prioritize community requests in our roadmap. Report issues or suggest features here.
📚 Documentation & Links
- 📖 Live Storybook Demo - Interactive examples
- 🤝 Contributing Guide - Workflow & bug reporting
- 📝 Releases & Changelog - Version history and release notes
- 📦 ngx-schematic-builder - Custom compiler for this project
License: BSD 2-Clause
Maintainer: Konrad Stępień (@kstepien3)
