# ng-select: an Angular select component that handles multiselect, autocomplete and large option lists

> ng-select is an MIT-licensed Angular component that replaces the native select element with a templated dropdown. This article covers how it binds values, how it installs, and where it stops being the right tool.

**ng-select/ng-select** — :star: Native angular select component

- Repository: https://github.com/ng-select/ng-select
- Website: https://ng-select.github.io/ng-select/
- Stars: 3,370 · Forks: 930
- Language: TypeScript
- License: MIT
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/ng-select-ng-select

## The gap ng-select fills in an Angular form

A native select element gives you keyboard handling and mobile behaviour for free, and it gives you almost nothing else. You cannot render a template per option, you cannot filter as the user types, and a multi-selection list is not part of the control at all. ng-select is built for that gap. The README describes it as a "Lightweight all in one UI Select, Multiselect and Autocomplete" and the feature list backs the claim: custom option, label, header and footer templates, client or server side filtering, custom tags, grouped items, keyboard navigation and accessibility.

The audience is Angular application teams. The repository is TypeScript, the package is published as @ng-select/ng-select, and the peer dependency is @angular/cdk. The README's version table maps each Angular release range to an ng-select major, from Angular >=22.0.0 <23.0.0 down to v23.x.x, back through v1.x for Angular 5. That long table is the clearest signal of who this is for: teams that stay on Angular and want one select control to cover single select, multiselect and typeahead instead of assembling three.

## How the binding model works

ng-select does not take an array of strings as its only input. It takes [items] plus two keys, bindLabel and bindValue. bindLabel decides what the user reads, bindValue decides what the form control stores. In the README's example the items are objects with id and name, and the markup is [items]="cars" bindLabel="name" bindValue="id". The form control then holds the id, not the object. You can set bindValue globally through the NgSelectConfig service, and override it per template with a bindValue attribute on the element.

That configuration service is also where the localization string lives. The README shows injecting NgSelectConfig and assigning this.config.notFoundText = 'Custom not found'. So the empty-result message is a global default, not a per-instance template concern, unless you supply your own not-found template.

On the rendering side, the feature list names CDK overlay positioning, described as "top-layer rendering, no clipping". This matters in real layouts: a select inside a scrollable container or a table cell is exactly where an absolutely positioned dropdown gets cut off. Because the panel is a CDK overlay rather than a child of the host element, positioning and stacking are handled by the CDK rather than by your container's overflow rules. The README also lists virtual scroll support for data sets above 5000 items and infinite scroll, which are the two mechanisms for lists that are too large to render at once.

## Installing ng-select and rendering a first multiselect

The README's first step is to install the package together with its @angular/cdk peer dependency. All three package managers are documented; the npm form is:

```bash
npm install --save @ng-select/ng-select @angular/cdk
```

The second step depends on which form API you use. For a standalone component with Signal Forms, the README imports NgSelectComponent along with NgLabelTemplateDirective and NgOptionTemplateDirective from @ng-select/ng-select, and the FormField directive from @angular/forms/signals. For Reactive Forms you import ReactiveFormsModule instead; for template-driven forms, FormsModule. NgModule applications import NgSelectModule and their forms module together.

The third step is easy to skip and produces a control that looks wrong. The bundle ships only generic layout and positioning styles, so the README tells you to import a theme into styles.scss or reference it from angular.json:

```scss
@import '~@ng-select/ng-select/themes/default.theme.css';
// ... or
@import '~@ng-select/ng-select/themes/material.theme.css';
```

After that, a working multiselect is a component property plus one element. The README defines the options on the component:

```typescript
@Component({...})
export class ExampleComponent {
	readonly cars = [
		{ id: 1, name: 'Volvo' },
		{ id: 2, name: 'Saab' },
		{ id: 3, name: 'Opel' },
		{ id: 4, name: 'Audi' },
	];
}
```

and binds them with a reactive form control:

```html
<ng-select [items]="cars" bindLabel="name" bindValue="id" [formControl]="selectedCarId" />
```

With that in place you should see a themed input that opens a panel listing Volvo, Saab, Opel and Audi, filters as you type, and writes the selected id into selectedCarId. Signal Forms use the same element with [formField]="carForm.selectedCarId" instead of [formControl], and the README notes that a raw signal value is not a valid formField binding: the binding must come from the tree returned by form().

## Version pinning is the real maintenance burden

The README carries an explicit warning: do not use versions 15.2.0, 16.0.0, 17.0.0, 18.0.0, 19.0.0 or 20.0.0 because they "contain unresolved issues". That is an unusual thing for a library to publish about its own releases, and it should shape how you upgrade. You cannot treat every published version as safe; the version table and the warning have to be read together before you bump.

The same README states that the library "is under active development and may have API breaking changes for subsequent major versions after 1.0.0". Combined with the version table, that means an Angular major upgrade usually forces an ng-select major upgrade, and each of those can carry breaking API changes. The package.json confirms the cadence: releases run through semantic-release on the master branch with a commit analyzer, so version numbers follow commit messages rather than a hand-curated plan.

There is a second, quieter cost. The package.json declares a postinstall script of patch-package and a prepare script of the same. If you build or install from the repository rather than consuming the published package, patch-package will run in your environment. That is worth knowing before you vendor the source into a monorepo. The build itself is not trivial either: the build script chains ng build for ng-select and ng-option-highlight, then sass compilation for the themes, then a copy of the SCSS sources into dist.

## When ng-select is the wrong component

If your form needs a short, fixed list of five options and no search, a native select is smaller, works without a theme import, and needs no peer dependency on @angular/cdk. ng-select's own README frames it as an all-in-one control for select, multiselect and autocomplete; that breadth is the cost. You take a component, a CDK overlay, a theme stylesheet and a version matrix in exchange for templating and filtering you may not need.

The larger risk is the version matrix itself. The README's table stops at Angular >=22.0.0 <23.0.0 mapped to v23.x.x, and the latest releases listed are v24.1.2, v24.1.1 and v24.1.0. If your application is on an Angular version outside the documented ranges, the README gives you no mapping, and the warning about specific broken versions means guessing is not a good strategy. Teams that cannot pin versions, or that upgrade Angular on a schedule they do not control, will feel this more than teams that plan upgrades together.

Accessibility is listed as a feature, but the README does not document its keyboard model, its ARIA attribute set or how it behaves with screen readers beyond that single line. If your project has a formal accessibility audit, that is a gap you will have to close by reading the source or the demo, not the README.

## How it differs from Angular Material's select

@angular/material/select is the comparison most Angular teams will make, and the difference is architectural rather than cosmetic. Material's select is one component inside a design system that also supplies your buttons, dialogs, form fields and typography; adopting it means adopting the theme system around it. ng-select is a single control. It depends on @angular/cdk for overlay positioning, but it does not bring a component library with it, and its own theming is limited to choosing between the default and material theme files or writing your own SCSS against the copied sources.

The practical consequence is that ng-select fits into an application that already has a visual language, while Material's select fits into an application that has adopted Material's. If you are already on Material, adding ng-select means two theming systems in one bundle. If you are not on Material, adding Material just for a multiselect means pulling in a design system to get one control. The README lists CDK overlay positioning as a feature, and that is the piece both approaches share; what differs is everything around it.

## Licence and what to verify before you ship

ng-select is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is the whole of the licence implication as far as this repository states it; nothing in the README adds a CLA, a commercial tier or a usage restriction. The peer dependency on @angular/cdk carries its own licence, which you should check separately since it is a distinct package with its own terms.

Before shipping, verify three things against your own project. First, which ng-select major the version table assigns to your Angular release, and whether that version appears in the README's list of versions to avoid. Second, which theme file you import and whether your build resolves the ~@ng-select/ng-select/themes/ path, since the README notes the bundle ships only generic styles. Third, whether your list sizes justify virtual scroll or infinite scroll, because the README documents those for data sets above 5000 items and they change how the panel behaves. The demo page at the project's homepage is the reference for behaviour the README does not spell out.

## Conclusion

Adopt ng-select if you are on a supported Angular version and need multiselect, typeahead or virtual scrolling over more than 5000 items, and you accept that major versions may change the API. Do not adopt it if a plain native select already meets your form requirements, or if you cannot pin a version: the README warns against 15.2.0, 16.0.0, 17.0.0, 18.0.0, 19.0.0 and 20.0.0. Before committing, check the Angular-to-ng-select version table against your own Angular release and confirm which theme file you will import.

## FAQ

### How do I install ng-select in an Angular project?

Install the package and its @angular/cdk peer dependency together, for example with npm install --save @ng-select/ng-select @angular/cdk. Then import NgSelectComponent (or NgSelectModule) plus the forms module you use, and import one of the theme stylesheets into your global styles.

### What is ng-select in Angular?

It is an Angular component published as @ng-select/ng-select that provides a select control with multiselect, autocomplete and templated options. The README describes it as a lightweight all in one UI Select, Multiselect and Autocomplete.

### How do I use ng-select in Angular?

Bind an array to [items] and set bindLabel and bindValue to the property names you want displayed and stored. Then connect it to a form with [formControl] for Reactive Forms, [formField] for Signal Forms, or ngModel for template-driven forms.

### How does ng-select differ from a native select element?

The README lists custom option, label, header and footer templates, multiselect, client or server side filtering, custom tags and CDK overlay positioning as features, none of which a native select provides. The trade-off is that you add a component, a theme stylesheet and a peer dependency on @angular/cdk.

### Is ng-select an alternative to Angular Material's select?

It can be, and the difference is scope. ng-select is a standalone control that depends on @angular/cdk for overlay positioning, while Material's select is one part of a full component library and theme system. Choosing ng-select does not commit you to Material's theming.

### What is ng-select used for compared with ng-select2?

The README positions ng-select as a single Angular control covering select, multiselect and autocomplete, with CDK overlay positioning and virtual scroll for data sets above 5000 items. It is an Angular component rather than a framework-independent wrapper, which is the main structural difference from a jQuery-era select plugin.

## Sources

- [License: MIT](https://github.com/ng-select/ng-select/blob/master/LICENSE)
- [ng-select/ng-select on GitHub](https://github.com/ng-select/ng-select)
- [Project website](https://ng-select.github.io/ng-select/)
- [README](https://github.com/ng-select/ng-select/blob/master/README.md)
- [Releases](https://github.com/ng-select/ng-select/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ng-select-ng-select
