Select
Searchable, virtualised select that handles 100k options. A drop-in select2 replacement.
npm install @devix-labs/select
A select that enhances the control you already have instead of replacing it, so forms, validation and server-rendered pages keep working. Search folds accents, Arabic and Urdu spellings and non-ASCII digits, ranks what it finds and highlights it; group headings stay with their matches; the list is windowed, so 100,000 options mount in under 80 ms; and the dropdown renders in the top layer, where no wrapper can clip it. Tags, remote data with abort and cache, a mobile sheet, and a CSS variable for every visual decision.
What you get
Enhances, never replaces
Your <select> stays in the form, hidden: FormData, validation, form.reset() and SSR all behave as they did.
9.5 KB, nothing else
Half the lightest competitor. select2 needs 29.6 KB of jQuery before it draws a single option.
100,000 options
A windowed list: sixteen rows in the DOM however far you scroll. Mounts in 76 ms, searches in 171 ms with the CPU throttled 4x.
Search that finds it
Accents, Arabic and Urdu letter shapes, Arabic-Indic digits, keywords and descriptions — ranked, highlighted, with a fuzzy rescue.
Nothing can clip it
The panel renders in the top layer, so overflow: hidden, modals and transformed parents cannot cut the dropdown off.
Wears your design system
CSS variables, classNames on every part, your own icons and row templates, a @layer stylesheet, and a headless core.
Select — overview
Why it exists
Every select on the market asks a page to pay for something it does not need: select2 needs jQuery, react-select needs React and emotion, Choices.js and Tom Select render every option into the DOM. The complaints under all of them are the same four: it is hard to style, the dropdown gets clipped, typing behaves oddly, and big lists crawl.
What it does differently
- Your
<select>stays the control. The widget is an enhancement, not a replacement, so forms, validation,FormData,form.reset()and server-rendered pages keep working. - 9.5 kB gzip, no dependencies — roughly half the lightest competitor, with more in it.
- A windowed list from the first option, so 100 000 options mount in 76 ms and search in 171 ms on a CPU throttled 4×.
- Search people can actually use: folded text (accents, Arabic, Urdu, non-ASCII digits), keywords, descriptions, ranked results, highlighted matches, and a fuzzy rescue only when nothing matched.
- The top layer for the panel, so no wrapper can clip it.
- Customisation as a first-class feature: variables,
classNames,icons,renderhooks,strings, a layered stylesheet and a headless core.
Shape of the package
| Entry | What |
|---|---|
@devix/select |
createSelect and the types |
@devix/select/core |
matching, ranking, grouping — no DOM |
@devix/select/react, /vue, /svelte, /element, /jquery |
wrappers over the same core |
@devix/select/styles.css, /styles.layer.css |
the theme, plain or inside @layer devix |
Not in 1.0
Tree select (parent/child), cascading selects (country → state → city) and a remote table picker are the Pro edition's shape, not gaps in the free core.
Demos
All demos →Enhance a <select>
The markup is a plain grouped <select>; the widget adds search, keywords, highlighting and a keyboard.
Multiple, with chips
Chips, a limit, chosen options taken out of the list, and Backspace to undo the last one.
Remote data
Debounced, aborted, cached and paged — the request count is shown as you type.
Tags
Free text becomes chips on Enter, comma or paste, with suggestions from a list you already have.
100 000 options
A windowed list: the DOM holds about sixteen rows however far you scroll, and search stays instant.
Theming
The same widget wearing four design systems — variables only, no stylesheet fork.
How it compares
Questions
Does my form still work?
Yes. The widget hides your <select> and keeps it in the form, so FormData, required, form.reset() and anything listening for change keep working. Values created at runtime get a real <option> so they post too.
How big can the list be?
We test at 100,000 options: about sixteen option elements exist at any moment, mounting takes 76 ms and a search 171 ms on a CPU throttled 4x, which is a mid-range phone. Bigger lists are a question of memory for your option objects, not of rendering.
Can I keep using select2's API?
On a page that already has jQuery, yes: the adapter registers $.fn.select2 when nothing else has, and translates placeholder, allowClear, multiple, tags, minimumInputLength, minimumResultsForSearch, data and ajax. Dropping jQuery is the bigger win, though.
Why is my dropdown not clipped by my modal any more?
The panel is shown with the Popover API, which puts it in the browser's top layer. Clipping ancestors, z-index stacks and transformed parents stop mattering.
Can I style it like the rest of my app?
Every visual decision is a CSS variable, every part takes your own classes, icons and row markup are replaceable, and the stylesheet also ships inside @layer devix so your CSS wins without !important. The styling guide has shadcn, Bootstrap and Material recipes.
Is it accessible?
It follows the WAI-ARIA combobox pattern: roles, aria-activedescendant, a live region that announces results and selections, full keyboard including type-ahead without a search box, forced-colours support and a touch sheet with 44px rows. The browser tests assert all of it.
More from Devix
All resources →Phone Input
UI component
International phone field with as-you-type formatting, validation and lazy per-country metadata.
Date Picker
UI component
Timezone-safe date picker with Hijri calendars, natural-language typing and a mobile sheet.
Date Range Picker
UI component
Ranges with presets, compare periods and multi-month views.