# ember-power-select: a select component built to be taken apart

> Ember Power Select is a combobox style select component for Ember that takes a different route from the native HTML select: it renders its own trigger, list and search field, and exposes every part for replacement. That flexibility costs you work, since you own the markup, the styling and the accessibility behaviour.

**ember-power-addons/ember-power-select** — The extensible select component built for ember.

- Repository: https://github.com/ember-power-addons/ember-power-select
- Website: http://ember-power-select.com/
- Stars: 540 · Forks: 375
- Language: TypeScript
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/ember-power-addons-ember-power-select

## It replaces the native select instead of wrapping it

Ember Power Select is a select component written in Ember with a focus in flexibility and extensibility, and the design decision that follows from that is the one that matters most: this is not a styled native select element.

The component renders its own trigger, its own list and its own optional search field. That gives it capabilities a native select cannot offer, and it gives you responsibilities a native select does not have. The readme lists flexible search placement, meaning you can render the search field inside the trigger or inside the dropdown list. Rich content rendering lets you put HTML or custom components inside options and triggers. Grouped options have no nesting limit, and placeholders are customizable.

The cost is visible in the feature list too. Theming support is described as easy CSS-based theming and design customization, CSS animations and transitions handle opening, closing and state changes, and accessibility is listed as accessible by default with full keyboard navigation, ARIA attributes and focus management built in. That last one is the item to read carefully. The word built in describes what the component does, not that you can ignore it. When you replace internal parts, the ARIA relationships and focus management those parts carried go with them.

So the component is best understood as a set of composable behaviours with a default presentation, rather than a finished widget you drop in. That framing is what the Extensions section of the readme is about, where the community is described as building richer and more tailor made components on top of it by using composition.

## Search that handles async data and promises properly

The selection and search half of the feature list is where the component has clearly been shaped by real application needs.

Filtering is diacritic-insensitive with accent sanitization, so a user typing without accents still matches. Custom matchers let you plug in your own matching and scoring logic, which is what you need when the default ranking is wrong for your data. Asynchronous search supports remote and delayed searching with debounce support, and the component is promise-aware, working with promises and async data.

The promise and ember-concurrency parts are the differentiating detail. The readme says the component is designed to work well with the way we build Ember apps, so it plays nicely with promises, ember-concurrency tasks and ember-data collections, and it follows idiomatic patterns. The feature list repeats that it is ember-concurrency friendly and works with task cancellation.

Task cancellation matters more than it sounds. A combobox that searches as you type will have several requests in flight at once, and if a slow earlier response overwrites a fast later one, the list shows results for a prefix you have already typed past. A component that integrates with ember-concurrency tasks can have the previous request cancelled when a new one starts, which removes that class of bug from your application code rather than asking every caller to handle it.

The component also supports single and multiple selection, clearable selections so the value can be reset, and disabled states for the whole component or for individual options. All of that is standard for a select, but the fact that the same component covers single and multiple in one implementation, rather than two, keeps the API surface smaller.

## TypeScript, Glint and the Ember v4.12 floor

The compatibility section is short and it is the part with hard requirements rather than preferences.

Compatibility is listed as Embroider or ember-auto-import v2, and Ember.js v4.12 or above. The badge in the readme states the same Ember version floor. This is an addon v2 format component, and the compatibility list says so directly with the line that it is Addon v2 ready in the modern Ember Addon v2 format.

Addon v2 matters more than it used to. The older addon format was built around the AMD loader and a build pipeline that Ember CLI generated per addon, and the v2 format is the direction the ecosystem moved so that addons can be consumed as standard packages and built with Vite. A component that requires Embroider or ember-auto-import v2 will not install into an application that has neither, and the requirement is not negotiable at the application level.

The typing story is good. The component ships type definitions for TypeScript integration, and it has Glint support for template type checking out of the box, which the readme describes as safer templates. The package.json confirms this in the exports map, where the main entry point exposes types, a sass entry and the default JavaScript build, and the wildcard entry exposes per module types alongside the built files.

The repository layout matches a modern addon. There is an addon-main.cjs, rollup.config.mjs for the build, a vite.config.mjs, babel configs for development and publishing, several tsconfig files including one for publishing, a .release-plan.json and a RELEASE.md. The demo-app directory holds the development playground, and the docs directory holds the documentation site, with a .env.development file alongside it. Styling is shipped in several formats, with scss and less directories, ember-power-select.scss, ember-power-select.less and a _index.scss, and the package files list includes them all so a consumer can pick the format their build pipeline handles.

## Installing the addon and running the test suite

Installation is a single package manager command, and the readme points to further detail in the installation documentation.

```bash
pnpm install ember-power-select
```

The command is written with pnpm, and the repository itself uses pnpm, with a pnpm-lock.yaml and a pnpm-workspace.yaml at the root, so the package manager is a choice the project has already made rather than an accident of the example.

The styles are the other half of the setup. The package exposes a sass field pointing at ember-power-select.scss and a style field pointing at the built vendor CSS, and the exports map offers the Less and SCSS entry points individually, including the base files under less/base.less and scss/base.scss and the variables files under less/variables.less and scss/variables.scss. A project that uses a preprocessor imports the variables file and overrides the values before the base; a project that does not can take the compiled CSS.

Testing is documented in the Testing section rather than in a contributing guide, and it is worth reading before you extend the component. It requires ember-cli-qunit, and the component provides test helpers for interacting with the component in acceptance tests, linked from the docs. That last point is a real signal about how the project expects itself to be used. A component that owns the trigger, the list and the search field needs an ergonomic way to drive those in a test, and shipping the helpers means your acceptance tests do not have to reverse engineer the internal DOM.

The build and lint commands in the package scripts are also conventional for the ecosystem: rollup for the build, prettier for formatting, and a lint script that runs the individual lint tasks concurrently with prefixed names and colours. The repository also carries an eslint config, a template lint config and a .prettierrc.mjs, so the formatting rules are enforced by tooling rather than by review comments.

## Where the flexibility stops paying off

The honest cost of this component is that it is not a native select, and every deviation from the native element is a decision you own.

A native select gets a great deal from the operating system for free. The dropdown is positioned by the browser, the picker on a phone is the platform picker, the accessibility semantics are correct because the element is correct, and the keyboard interaction is the one every user already knows. This component replaces all of that with markup it renders itself, and the readme is explicit that you control the markup and styling. The Shadow DOM support entry, which says the component can be rendered inside shadow roots without breaking positioning or events, is a good sign about how much of that work has been done, but it is also an admission that positioning and events are the component's problem to solve rather than the browser's.

The second limitation is the version floor and the addon format. Ember 4.12 or above, plus Embroider or ember-auto-import v2, rules out applications on older Ember versions and applications that have not moved to the v2 build model. For a greenfield application in 2026 that is a reasonable requirement, but for a long lived application on an older toolchain it is a blocker rather than a cost.

The third is the composability trap. Because any internal part can be replaced with your own components, it is easy to build a version of this component that is no longer accessible. The ARIA attributes, keyboard navigation and focus management that the readme lists as built in are attached to the default parts. Replace the list and you own the list's ARIA relationships, and the readme does not document a contract your replacement must satisfy. The composability is the feature, but it is also the sharpest edge.

The alternative to weigh against it is a plain native select styled with CSS, or a headless combobox primitive that keeps the ARIA relationships in one place and lets you render the visual parts. The difference in approach is where the accessibility contract lives. The native select puts it in the browser and gives you nothing to customise. A headless primitive keeps it in the library but separates it from the visuals, so customising the markup does not mean reimplementing the semantics. This component puts the semantics and the visuals in the same replaceable package, which is more convenient while you accept the defaults and more work once you do not.

## Maintenance pace and the contribution agreement

The release history is regular, and it carries a major version number that tells you something about the project's maturity.

The recent versions are v9.0.3 on 2026-10-12, v9.0.2 on 2026-07-28 and v9.0.1 on 2026-06-29, and the last push to the repository was on 2026-10-17. So the project is being worked on and the patch releases land regularly. At version 9, the component has also been through enough years of Ember changes that a major version bump is a routine event rather than a sign of instability.

The build tooling follows the same evolution. Vite alongside Rollup, a release plan configuration, a CHANGELOG.md and a RELEASE.md in the root, and a dist directory in the exports with a vendor subdirectory for the compiled CSS, all point to a project that tracks the ecosystem's recommended setup rather than a frozen addon.

The contribution guidance is specific in a way that is worth reading before you open a pull request. Any contribution is welcome and the guidelines are in CONTRIBUTING.md, but if the contribution involves adding a new feature the guidance asks you to open an issue first, to share the plan and agree the details of the feature before starting to implement it. That is a reasonable arrangement for a component with this much surface area, since a new feature touches the default parts, the extension points and the test helpers at once.

For bug reports there is a similar expectation about detail. The troubleshooting section asks you to visit the troubleshooting documentation first, and to open an issue if the problem persists, specifying the version of the component, Ember and browser. That is the right information to have, because a select component's behaviour varies with the browser's own focus and positioning behaviour, and a report without those three versions is much harder to act on.

The licence is MIT, stated in the package.json and in a LICENSE.md file, which is the permissive end; the only real obligation is to keep the copyright notice and licence text when redistributing. The project also points to a Discord channel and carries an Ember Observer badge, both of which are places where the wider community can be reached.

## Conclusion

Ember Power Select suits an Ember application that needs a combobox with async search and multiple selection and wants to own the markup and styles, and it does not suit a project that wants a native select element with browser behaviour and zero styling work, because the component replaces the native element entirely. Before you adopt it, confirm your Ember version is 4.12 or above and that you use Embroider or ember-auto-import v2, then decide whether your team will maintain the component's CSS and the accessibility behaviour it delegates to you, and read the troubleshooting page before filing an issue, since the maintainers ask for the component version, Ember version and browser when a problem persists.

## FAQ

### What is Ember Power Select and what does it replace?

It is a select component written in Ember that renders its own trigger, list and optional search field rather than wrapping a native HTML select. That makes features like async search, rich option content and grouped options possible, at the cost of owning the markup and styling.

### How do I install ember-power-select?

Run pnpm install ember-power-select. Further installation details, including how to wire in the styles from the scss or less entry points, are in the installation documentation on the project site.

### Which Ember versions does ember-power-select support?

Ember.js v4.12 or above, together with Embroider or ember-auto-import v2. The component is in the modern Ember Addon v2 format and ships TypeScript types with Glint template type checking.

### Does ember-power-select support async search and promises?

Yes. Asynchronous search supports remote and delayed searching with debounce, the component is promise-aware, and it is designed to work with ember-concurrency tasks including task cancellation.

### How do I test an app that uses ember-power-select?

Testing requires ember-cli-qunit, and the component ships test helpers for interacting with it in acceptance tests. If a problem persists, the troubleshooting documentation should be checked before opening an issue with the component, Ember and browser versions.

## Sources

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

---

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