ng-select

A native Angular select, multiselect, and autocomplete component with built-in support for Signal, Reactive, and Template-driven Forms.

Library
npm
v24.1.1
3,372stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
92/100Excellent
Development Activity92
Maintenance92
Community84
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
79/100Good
Architecture82
Code Quality84
Innovation68
Learning Curve80

ng-select is the de facto Angular replacement for the browser’s native <select> when an application needs multiselect, tagging, grouping, virtual scrolling over large datasets, or asynchronous client/server-side filtering. It ships as a standalone NgSelectComponent (with an NgSelectModule for NgModule-based apps) and implements ControlValueAccessor, so it drops straight into Angular’s Signal Forms, Reactive Forms, or template-driven ngModel bindings without any adapter code.

The component is under active, fast-moving development: as of this write-up the maintainers are shipping multiple releases per week, and the project just completed a significant internal rewrite. Since v24, dropdown panel positioning was moved off a hand-rolled geometry calculation onto Angular CDK’s Overlay (using the native Popover API top layer where available), which fixes long-standing z-index and clipping issues against things like Bootstrap modals. The public component itself was also rewritten onto Angular’s newer signal-based APIs (input(), model(), linkedSignal(), computed()) while preserving the original property-based public API through backing signals, so existing consumers upgrade without template changes.

Its closest competitors in the Angular ecosystem are Angular Material’s mat-select/mat-autocomplete and PrimeNG’s Dropdown/MultiSelect — ng-select’s pitch is being framework-styling-agnostic (bundled default and Material themes, but no dependency on Angular Material or a full component-suite install) while covering more selection UX out of the box (tagging, grouping, custom templates for every slot, virtual scroll) than Material’s stock select alone.

What You Get

  • A <ng-select> component supporting single-select, multiselect, autocomplete, and free-form tag creation from one API surface
  • Directive-based template slots for label, option, header, footer, loading, not-found, and placeholder content (NgLabelTemplateDirective, NgOptionTemplateDirective, etc.)
  • Virtual scroll support for rendering large option sets (5000+ items) without per-item DOM cost
  • CDK Overlay-based dropdown panel positioning (top-layer rendering via the native Popover API) that isn’t clipped by ancestor overflow: hidden or stacked below modals
  • Full keyboard navigation and accessibility (ARIA) support out of the box
  • Bundled default and Material themes, distributed as separate SCSS/CSS files under package exports

Common Use Cases

  • Replacing a native <select> in a form when the app needs multiselect, search-as-you-type filtering, or tagging
  • Country/currency/timezone pickers backed by a large static list, using virtual scroll to keep the dropdown responsive
  • Server-side typeahead search (e.g. searching users or products by name) via the typeahead input driving an async fetch
  • Grouped option lists (e.g. products grouped by category) using the built-in groupBy/groupValue inputs
  • Custom tag creation where users can add values not present in the source list via addTag

Under The Hood

Architecture A single NgSelectComponent implementing ControlValueAccessor sits at the root, composing an ItemsList helper (owns source/filtered/grouped/marked/selected option state), a pluggable SelectionModel (single vs. multi selection behavior, swappable via a DI token), and a separate NgDropdownPanelComponent plus NgDropdownPanelService for the actual overlay panel, coordinated through a dedicated overlay-manager class that wraps Angular CDK’s Overlay. Template customization is handled entirely through structural directives (one per template slot: label, option, header, footer, loading, not-found, and more) rather than component inputs, which keeps the component’s own API surface relatively small despite covering an extensive set of visual overrides. Note for maintainers: an older parallel copy of the top-level component still exists in the source tree but isn’t referenced from the package’s public entry point or from any other library file, suggesting a leftover from an in-progress rewrite rather than active dead code risk for consumers.

Tech Stack Built against a current Angular major version, with @angular/cdk as a peer dependency specifically for overlay positioning. RxJS handles search-input debouncing and async tag-resolution flows. The library is packaged with ng-packagr into a standard Angular Package Format distributable, with themes authored in SCSS and compiled separately so consumers can import only the theme they need. The repository is a pnpm workspace that also builds a companion highlighting-directive package alongside the core library, with semantic-release automating npm publishing from conventional commits.

Code Quality Test coverage is extensive relative to the size of the library, run through a modern browser-based test runner with coverage reporting wired into CI alongside linting, a full demo build, and CodeQL static analysis on every change. Error handling favors explicit thrown errors with descriptive messages for programmer mistakes (an invalid compareWith function, an unresolvable appendTo selector), while a handful of async failure paths are deliberately swallowed as a UX choice rather than surfaced — worth knowing about if you lean on custom async tag validation. Lint configuration relaxes a couple of default TypeScript strictness rules (unused-vars and explicit-any checks are turned off project-wide), a minor tradeoff against otherwise disciplined tooling.

API Design The component exposes one consistent surface across every Angular forms paradigm it supports — Signal Forms, Reactive Forms, and template-driven forms all bind to the same component without adapters. Recent internal work migrated the component’s state management onto Angular’s newer signal primitives while preserving the original property-based public API, so upgrades are largely non-breaking for consumers even as internals changed substantially. Documentation is a genuine strength: the README carries a detailed, example-driven migration guide for the overlay-positioning change, covering DOM location, stacking context, and theme-authoring implications rather than a one-line changelog entry.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search