npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ngwr

v12.1.0

Published

Signals-first Angular UI library: 100+ standalone, zoneless-ready components with native Signal Forms, SSR-safe rendering and CSS-variable theming.

Downloads

2,406

Readme

ngwr website ngwr version angular peer ci coverage license

NGWR is an Angular UI library that binds straight to Signal Forms. Nineteen value controls implement FormValueControl / FormCheckboxControl themselves, so [formField] writes the component's own value / checked model — there is not one ControlValueAccessor in the library. Zoneless by construction, not zoneless-compatible: signal inputs, signal state, afterNextRender() for DOM work, and no @NgModule or @Input() decorator anywhere in the source. 202 tree-shakable entry points, on @angular/cdk for overlay, portal and a11y primitives.

Try it in the browser — no install. How it compares — what the other Angular UI libraries do about Signal Forms today, counted rather than asserted. Docs and live demos.

import { Component, signal } from '@angular/core';
import { FormField, email, form, required } from '@angular/forms/signals';
import { WrCheckbox } from 'ngwr/checkbox';
import { WrFormField } from 'ngwr/form';
import { WrInput } from 'ngwr/input';

@Component({
  selector: 'signup-card',
  imports: [FormField, WrCheckbox, WrFormField, WrInput],
  template: `
    <wr-form-field label="Work email" required>
      <input wrInput type="email" [formField]="signup.email" />
    </wr-form-field>

    <wr-checkbox [formField]="signup.agree">I agree to the terms</wr-checkbox>
  `,
})
export class SignupCard {
  private readonly model = signal({ email: '', agree: false });

  // `[formField]` binds to the control's own `value` / `checked` model, and
  // `<wr-form-field>` resolves the error copy from the i18n catalog — so
  // neither an accessor nor a `<wr-form-error>` has to be written by hand.
  readonly signup = form(this.model, path => {
    required(path.email);
    email(path.email);
  });
}

Classic [(ngModel)] and reactive forms still work — Angular 22 synthesises the accessor for a signal-forms control — and every control is usable standalone through its two-way [(value)] / [(checked)] model.

Status: active development. v12 is the current major line (Angular 22 peer). Public API is stable across patch releases and still evolving between majors. Open an issue if something breaks or feels wrong.

Requirements

| Peer | Range | | ------------------------------ | -------------------- | | @angular/core | >= 22.0.0 | | @angular/common | >= 22.0.0 | | @angular/forms | >= 22.0.0 | | @angular/cdk | >= 22.0.0 | | @angular/platform-browser | >= 22.0.0 | | @angular/router (optional) | >= 22.0.0 | | rxjs | ^7.0.0 | | date-fns (optional) | ^3.0.0 \|\| ^4.0.0 | | luxon (optional) | ^3.0.0 | | lucide (optional) | >= 1.0.0 |

TypeScript ~6.0.x (Angular 22's compiler declares typescript >=6.0 <6.1) and a Node version Angular 22 accepts — ^22.22.3 || ^24.15.0 || >=26. Contributing to this repo needs the narrower ^24.16.0 || >=26 it pins (.nvmrc says 24), plus pnpm ≥ 11.10.

Install

The schematic does the whole Install + Styles section for you — it installs ngwr and its peers, appends @use 'ngwr'; to your global stylesheet, and prints a provider snippet tailored to your answers (date adapter, density, theme) to paste into bootstrap:

ng add ngwr

Or wire it up by hand:

pnpm add ngwr @angular/cdk
# or
npm install ngwr @angular/cdk
# or
yarn add ngwr @angular/cdk

Beyond Angular itself, @angular/cdk and @angular/forms are the required peers — forms because the value controls implement its Signal Forms interfaces. @angular/router is optional, needed only by the navigation components that take a routerLink. A stock ng new app already ships forms and router, so @angular/cdk is the only one you have to add — which is why it is on the install lines above. Add an icon set and a date library only if you use them — lucide (or feather-icons) for the icon adapters, and date-fns or luxon for the calendar / date-picker, which otherwise runs on a built-in native Date adapter. The Quick start below registers a lucide icon, so it needs lucide:

pnpm add lucide

Styles

The fastest way — pull in everything (theme tokens + all component styles):

// styles.scss
@use 'ngwr';

Good for a spike, but it is every entry point at once — about 265 kB of CSS (~40 kB over the wire), which is over half the 500 kB initial budget a fresh ng new warns at before any of your own code. For anything you intend to keep, opt in per component below and the sheet stays proportional to what you actually render.

Prefer to opt in per-component? Each component has its own SCSS entry that pulls in the theme automatically:

@use 'ngwr/theme'; // CSS custom properties (--wr-color-*, --wr-font-*, etc.)
@use 'ngwr/button';
@use 'ngwr/input';
@use 'ngwr/checkbox';

Opt-in utilities (not part of @use 'ngwr'):

@use 'ngwr/reset'; // box-sizing, body margin, sane defaults
@use 'ngwr/grid'; // .grid, .container, .col-*
@use 'ngwr/animations'; // .wr-animate-fade-in, .wr-animate-slide-up, …
@use 'ngwr/typography-utilities'; // .wr-text-*, .wr-font-* utility classes
@use 'ngwr/breakpoints' as bp; // SCSS mixins only, no CSS output

ngwr/typography-utilities is the utility-class sheet — not ngwr/typography, which is the larger wrTypography component entry.

Quick start

// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideWrOverlay } from 'ngwr/overlay';

import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent, {
  providers: [
    provideWrOverlay(), // isolated overlay container
  ],
});
// app.component.ts
import { Component, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { Check } from 'lucide';
import { WrButton } from 'ngwr/button';
import { provideWrIcons } from 'ngwr/icon';
import { lucideIcons } from 'ngwr/icon/adapters/lucide';
import { WrInput } from 'ngwr/input';

@Component({
  selector: 'app-root',
  imports: [FormsModule, WrButton, WrInput],
  providers: [provideWrIcons(lucideIcons({ checkmark: Check }))], // tree-shaken icons
  template: `
    <input wrInput [(ngModel)]="name" placeholder="Your name" />
    <button wr-btn color="primary" icon="checkmark" (click)="greet()">Hello</button>
  `,
})
export class AppComponent {
  readonly name = signal('');
  greet(): void {
    console.log('Hi', this.name());
  }
}

Value controls are Signal Forms-native, so [formField] binds straight through — no ControlValueAccessor anywhere in the chain:

// profile-form.ts
import { Component, signal } from '@angular/core';
import { FormField, form } from '@angular/forms/signals';
import { WrCheckbox } from 'ngwr/checkbox';
import { WrInput } from 'ngwr/input';

@Component({
  selector: 'app-profile-form',
  imports: [FormField, WrCheckbox, WrInput],
  template: `
    <input wrInput [formField]="profile.name" placeholder="Your name" />
    <wr-checkbox [formField]="profile.agree">I agree</wr-checkbox>
  `,
})
export class ProfileForm {
  readonly model = signal({ name: '', agree: false });
  readonly profile = form(this.model); // FieldTree — profile.name, profile.agree
}

Catalog

Browse the full catalog with live demos at ngwr.dev. Each entry below is a tree-shakable subpath — import { … } from 'ngwr/<name>'. A few share a package: form-field ships from ngwr/form, button-group from ngwr/button, and qr is the subpath behind the qrcode docs page.

Components

Formcalendar, cascader, checkbox, color-picker, date-picker, file-upload, form, form-field, input, input-number, input-otp, knob, mention, radio, rating, segmented, select, slider, switch, textarea, transfer.

Buttonsbutton, button-group, speed-dial.

Datadrag-drop, event-calendar, pagination, pull-to-refresh, table, tree, virtual-scroll.

Feedbackalert, empty, progress, result, skeleton, spinner.

Displayavatar, badge (incl. wr-tag), compare, counter, descriptions, divider, image-cropper, keyboard, lightbox, markdown, qr, statistic, timeline.

Layoutcard, carousel, collapse, layout, list, page-header, splitter, toolbar.

Navigationanchor, back-top, breadcrumbs, burger, dropdown, sidebar, stepper, tabs.

Overlaysaction-sheet, command-palette, context-menu, dialog, drawer, popconfirm, popover, toast, window.

Chartsbar-chart, calendar-heatmap, donut-chart, gauge, line-chart, meter-group, sparkline.

Plus icon, the experimental squircle, and the typography directive.

Animations

Animated UI effects. Mix of in-house components + ports of reactbits.dev — each port carries a credit chip on its docs page. Defaults are theme-aware (light + dark), and every component honors prefers-reduced-motion — the one exception is spotlight-card, whose highlight only tracks the pointer.

aurora, blur-text, border-glow, circular-text, click-spark, confetti, decrypt-text, falling-text, fuzzy-text, glitch-text, gradient-text, marquee, rotating-text, shiny-text, splash-cursor, split-text, spotlight-card, star-border, tilt-card, typewriter, waves.

Card packages bundle their related directives: ngwr/spotlight-card exports WrSpotlight; ngwr/tilt-card exports WrTilt; ngwr/shiny-text exports WrShimmer.

Directives — ngwr/directives

autofocus, autosize, click-outside, copy-to-clipboard. affix ships as its own entry (ngwr/affix).

Pipes — ngwr/pipes

wrBytes, wrDate, wrMark, wrNumber, wrPlural, wrRange, wrTruncate.

Services

clipboard, cookie, density, hotkey, loading-bar, media, meta, platform, scroll, storage, theme, tour, i18n.

Validators — ngwr/validators

Bundled ValidatorFns composing cleanly with Angular's built-in Validators: cardNumber (Luhn), cvc, hexColor, iban (mod-97), match (sibling control), matchFields (group-level), maxDate, minDate, noWhitespace, oneOf, url. See docs.

Utils — ngwr/utils

Math (clamp, round), coercion (numAttr), css helpers (resolveCssSize, getRootFontSize), ids (randomId), type guards (isDefined, isNonEmptyArray, isObservable), keyboard helpers (KEYS, hasModifier, isPrintableKey), functional primitives (noop, badgeLog, debounce, throttle), focus management (getFocusableElements, trapFocus). See docs for the full list. Shared shapes (Maybe, SafeAny, WrColor, …) are documented under Interfaces.

Core

  • Color — design tokens and palette.
  • Grid — opt-in 12-column layout.
  • Overlay — isolated CDK overlay container, provideWrOverlay().
  • Mobile & responsive — responsive overlays, touch targets & density, swipe gestures, safe-area insets, container-query layouts.
  • TypographywrTypography directive: headings, paragraphs, lists, links, code.
  • Iconsngwr/icon registry. Use svgIcon() for any set that ships raw SVG files (Tabler, Phosphor, Heroicons, Iconoir, Radix, Bootstrap, or your designer's own), plus thin adapters for Lucide (ngwr/icon/adapters/lucide) and Feather (ngwr/icon/adapters/feather), whose packages don't ship SVGs.
  • Date adaptersngwr/date (native Date, no extra package), ngwr/date/adapters/fns, ngwr/date/adapters/luxon. Wire one with provideWrDateAdapter() — plus { adapter: WrDateFnsAdapter } / { adapter: WrLuxonAdapter } for the library-backed ones — to power calendar + every mode of date-picker.
  • Component defaultsngwr/config. provideWrConfig({ button: { size: 'sm' } }) sets what a component falls back to when a template says nothing; a bound value always wins, and a bound false beats a configured true, so a config never has to be escaped. Reference.

Highlights

  • Standalone & signals-first. Every component is standalone and uses input() / model() / output() / signal() / computed(). Zoneless-ready.
  • Signal Forms native. Nineteen value controls implement FormValueControl / FormCheckboxControl, so [formField] binds straight through — there is no ControlValueAccessor in the library at all. [(ngModel)] and reactive forms keep working through Angular's bridge, and every control also works standalone via [(value)] / [(checked)].
  • CDK-powered. Overlays, portals, and a11y come from @angular/cdk. We add provideWrOverlay() so NGWR overlays never collide with other CDK consumers (Material, NG-ZORRO, etc.).
  • Mobile & responsive. Overlays collapse to bottom-sheets on small screens (provideWrResponsiveOverlays()), touch targets grow to ≥44px on coarse pointers, a touch density preset enlarges the nine control families that read the multipliers, and drawer / lightbox / toast / carousel respond to swipe gestures. Fixed surfaces respect env(safe-area-inset-*), and layout components (descriptions, stepper, page-header, toolbar, pagination, table) reflow to their container via container queries. Guide.
  • Table, batteries included. wr-table covers column pinning / resizing / drag-reorder, row selection, expandable rows, grouping, tree rows (childrenKey — the forest flattens into the same <tbody>, so pinning and cell templates keep working at every depth, and the table announces a treegrid), summary rows, CSV export (exportCsv(), dependency-free RFC 4180) and a virtualized body — all opt-in inputs on the one component. Excel (.xlsx) export is deliberately not shipped: it would mean a third-party dependency.
  • Tree-shakable. 202 separate ng-packagr entry points — import only what you use. Per-component FESM bundles are small: a median of ~4 KB gzipped, the heaviest (ngwr/markdown) ~23 KB. Every runtime bundle together gzips to ~690 KB — the 70 ngwr/<name>/testing harnesses aside, since they never reach an app bundle — but real apps pull a handful of entries. The only runtime dependency is tslib.
  • Modular SCSS. Component styles are scoped through CSS custom properties. Theme tokens live in ngwr/theme; utilities (grid, reset) and the breakpoints SCSS API are opt-in.
  • Tree-shaken icons. provideWrIcons(lucideIcons({ plus: Plus })) registers only the icons you actually import. Dev-mode validation warns about unregistered icons.
  • Reactbits ports, dependency-free. All animation ports are reimplemented with vanilla DOM + Web Animations API / IntersectionObserver / requestAnimationFrame / raw WebGL — no GSAP, no motion/react, no matter-js, no ogl.
  • Motion respects the OS. Every animation component short-circuits to its final state under prefers-reduced-motion, except spotlight-card, which animates nothing on its own — its highlight follows the cursor.
  • Legible to agents. Every docs page also serves as markdown at the same URL plus .mdreference/components/select.md is that page's prose, code samples and API tables without the site chrome. The whole catalog is at llms-full.txt, a quick-ref at llms.txt.

MCP server

The package ships ngwr-mcp, a zero-dependency MCP server that makes those files askable: search_ngwr (find an entry point by what you need), get_ngwr_component, get_ngwr_api (a class's inputs / models / outputs / methods, read out of the shipped .d.ts) and get_ngwr_setup (the install, ng g ngwr:use and provider commands — returned as text; it never runs them). It adds no second copy of the catalog: it reads only files inside its own installed package, makes no network requests, and runs no commands.

{
  "mcpServers": {
    "ngwr": { "command": "npx", "args": ["-y", "ngwr-mcp"] }
  }
}

Works in Claude Code (claude mcp add ngwr -- npx -y ngwr-mcp), Claude Desktop and Cursor. To pin it to the version in your lockfile, use "command": "node", "args": ["./node_modules/ngwr/mcp/server.js"]. Guide.

Contributing

Conventional commits are enforced on PR titles. Common types: feat, fix, perf, refactor, docs, style, test, build, ci, chore, revert. Optional scope is the component or area (feat(checkbox): icon mode).

pnpm install
pnpm dev            # ng serve --o (showcase)
pnpm test           # ng test lib (vitest)
pnpm build:lib      # ng build lib + ai assets + dist assets + i18n json + schematics + mcp server
pnpm build:showcase # ai assets + showcase build + sitemap + markdown twins
pnpm lint           # ng lint + eslint scripts + stylelint + colour parity + rtl

Authors

License

MIT — free for commercial use.