ng-select
A native Angular select, multiselect, and autocomplete component with built-in support for Signal, Reactive, and Template-driven Forms.
Repository Health
Technical Analysis
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: hiddenor 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
typeaheadinput driving an async fetch - Grouped option lists (e.g. products grouped by category) using the built-in
groupBy/groupValueinputs - 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.
Used by 2 apps in this directory
OpenProject
Project Management · Productivity · Collaboration
The open source project management platform that unifies Gantt charts, agile boards, time tracking, and team collaboration under full self-hosted control.
Paperless-ngx
Bookmarks Archiving
Turn your paper pile into a searchable digital archive with OCR, AI classification, and automated workflows — all running on your own server.