npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@referralgps/selectra

v1.0.10

Published

Selectra — A powerful, extensible <select> UI control for tagging, contact lists, country selectors, and autocomplete. Built with Alpine.js and Tailwind CSS.

Readme

Selectra

npm version npm downloads license GitHub stars

A powerful, extensible <select> UI control — rebuilt with Alpine.js and Tailwind CSS.

Live Demo →

Selectra is a modern rewrite of Selectize.js, designed for tagging, contact lists, country selectors, and autocomplete. It drops the jQuery dependency entirely in favor of Alpine.js reactivity and Tailwind CSS styling.


Why Selectra?

| | Selectize.js (legacy) | Selectra | |---|---|---| | UI Framework | jQuery | Alpine.js | | Styling | LESS / SCSS + Bootstrap themes | Tailwind CSS utilities | | Build Tool | Gulp | Vite | | Tests | Karma + Mocha | Vitest | | Bundle (JS) | ~88 KB min | ~25 KB min | | CSS | Multiple theme files | Single 21 KB utility file | | jQuery Required | Yes | No |


Features

  • Single & Multi Select — auto-detected from maxItems or explicit mode
  • Tagging / Create — create new options on the fly with validation
  • Fuzzy Search — built-in Sifter engine with diacritics support
  • Remote Loading — fetch options from API with debounced requests
  • Option Groups — grouped options with sticky headers
  • Keyboard Navigation — arrows, enter, escape, tab, backspace, ctrl+A
  • Copy / Paste — split pasted text into multiple items via delimiter
  • Custom Rendering — templates for options, items, create prompt, no-results, loading
  • Plugin System — 9 built-in plugins, easy to create custom ones
  • Accessible — focus management, label association, keyboard-first
  • RTL Support — auto-detected from CSS direction
  • Tailwind CSS — fully styled with utilities, trivially customizable
  • Selected Count Mode — show a count badge instead of tags in multi-select, with checkmarks on selected options
  • Array-Format Options — pass [text, value] tuples directly (e.g. from Rails pluck)
  • Lightweight — ~25 KB gzipped JS, zero runtime dependencies beyond Alpine.js

Requirements

  • Node.js v14 or newer (for npm/yarn install)
  • Alpine.js v3.x (peer dependency)
  • Tailwind CSS v2.x or v3.x (for styling, optional but recommended)

Installation

npm install @referralgps/selectra alpinejs

Import and register the plugin in your JavaScript entry point:

import Alpine from 'alpinejs';
import Selectra from '@referralgps/selectra';
import '@referralgps/selectra/css';

Alpine.plugin(Selectra);
Alpine.start();

Quick Start

Add x-data="selectra({...})" and x-selectra to any element. The template is rendered automatically by the x-selectra directive — no manual markup required.

Single Select

<div x-data="selectra({
  mode: 'single',
  placeholder: 'Select a country...',
  options: [
    { value: 'us', text: 'United States' },
    { value: 'ca', text: 'Canada' },
    { value: 'mx', text: 'Mexico' },
  ]
})" x-selectra></div>

Multi Select with Tags

<div x-data="selectra({
  mode: 'multi',
  placeholder: 'Select languages...',
  create: true,
  options: [
    { value: 'js', text: 'JavaScript' },
    { value: 'py', text: 'Python' },
    { value: 'go', text: 'Go' },
  ]
})" x-selectra></div>

Multi Select with Count Badge

Show the number of selected items as a badge instead of individual tags. Selected options display a ✓ checkmark in the dropdown and can be toggled on/off by clicking.

<div x-data="selectra({
  mode: 'multi',
  showSelectedCount: true,
  placeholder: 'Select countries...',
  options: [
    { value: 'us', text: 'United States' },
    { value: 'ca', text: 'Canada' },
    { value: 'mx', text: 'Mexico' },
  ]
})" x-selectra></div>

Form Field Name

Use the name option to auto-create a hidden <input> for form submission — no <select> element needed:

<form method="POST" action="/submit">
  <div x-data="selectra({
    mode: 'multi',
    name: 'languages',
    placeholder: 'Select languages...',
    options: [
      { value: 'js', text: 'JavaScript' },
      { value: 'py', text: 'Python' },
      { value: 'go', text: 'Go' },
    ]
  })" x-selectra></div>
  <button type="submit">Submit</button>
</form>

Array-Format Options

Pass options as [text, value] tuples — ideal for data from Rails pluck or similar:

<div x-data="selectra({
  mode: 'single',
  placeholder: 'Select provider...',
  options: [
    ['Aetna Better Health', 121],
    ['Blue Cross Blue Shield', 205],
    ['Cigna Healthcare', 310],
  ]
})" x-selectra></div>

Native <select> Enhancement

Enhance a standard <select> element — options are read automatically:

<div x-data="selectra()" x-selectra>
  <select>
    <option value="">Pick a fruit...</option>
    <option value="apple">Apple</option>
    <option value="banana">Banana</option>
    <option value="cherry">Cherry</option>
  </select>
</div>

Configuration

| Option | Type | Default | Description | |--------|------|---------|-------------| | mode | 'single' \| 'multi' | auto | Selection mode | | options | Array | [] | Available options | | items | Array | [] | Pre-selected values | | maxItems | number \| null | null | Max selectable items | | maxOptions | number | 1000 | Max dropdown options | | create | boolean \| function | false | Allow creating new options | | createOnBlur | boolean | false | Create item when field loses focus | | createFilter | RegExp \| function | null | Filter for creatable values | | placeholder | string | '' | Placeholder text | | name | string \| null | null | Form field name — auto-creates hidden input when no source element exists | | valueField | string | 'value' | Property for option value | | labelField | string | 'text' | Property for display label | | searchField | string[] | ['text'] | Fields to search | | searchConjunction | 'and' \| 'or' | 'and' | Multi-term search logic | | sortField | string \| Array | '$order' | Sort field(s) | | highlight | boolean | true | Highlight matches | | openOnFocus | boolean | true | Open dropdown on focus | | selectOnTab | boolean | true | Tab selects active option | | closeAfterSelect | boolean | false | Close dropdown after selection | | hideSelected | boolean \| null | auto | Hide selected from dropdown | | showSelectedCount | boolean | false | Show count badge instead of tags in multi-select | | delimiter | string | ',' | Value separator | | splitOn | RegExp \| string | null | Regex for splitting pasted values | | diacritics | boolean | true | International character support | | normalize | boolean | true | NFD normalize search queries | | preload | boolean \| 'focus' | false | Preload options | | load | function \| null | null | Remote data loader | | loadThrottle | number | 300 | Load debounce delay (ms) | | plugins | Array | [] | Plugins to activate | | dropdownPlaceholder | string | '' | Pre-search placeholder

Custom Rendering

selectra({
  render: {
    option: (data, escape) => `<div class="flex items-center gap-2">
      <img src="${data.avatar}" class="w-6 h-6 rounded-full">
      <span>${escape(data.text)}</span>
    </div>`,
    item: (data, escape) => escape(data.text),
    optionCreate: (data, escape) => `Add "${escape(data.input)}"`,
    noResults: () => 'Nothing found',
    loading: () => 'Searching...',
  }
})

Remote Loading

selectra({
  load: (query, callback) => {
    fetch(`/api/search?q=${encodeURIComponent(query)}`)
      .then(res => res.json())
      .then(data => callback(data.results))
      .catch(() => callback([]));
  },
  loadThrottle: 300,
})

API Methods

| Method | Description | |--------|-------------| | addOption(data) | Add one or more options | | updateOption(value, data) | Update an existing option | | removeOption(value) | Remove an option | | clearOptions() | Remove all options (keeps selected) | | getOption(value) | Get option data by value | | addItem(value) | Select an item | | removeItem(value) | Deselect an item | | clear() | Clear all selections | | getValue() | Get current value(s) | | setValue(value) | Set selected value(s) | | createItem(input?) | Create new item from input | | open() | Open dropdown | | close() | Close dropdown | | focus() | Focus the control | | blur() | Remove focus | | lock() / unlock() | Temporarily disable input | | disable() / enable() | Disable/enable control | | setMaxItems(max) | Update max items limit |

Events

Events are dispatched as custom DOM events on the wrapper element:

el.addEventListener('selectra:change', (e) => {
  console.log('Value changed:', e.detail);
});

| Event | Detail | |-------|--------| | selectra:change | [value] | | selectra:itemadd | [value, data] | | selectra:itemremove | [value] | | selectra:clear | [] | | selectra:optionadd | [value, data] | | selectra:optionremove | [value] | | selectra:dropdownopen | [] | | selectra:dropdownclose | [] | | selectra:type | [query] | | selectra:focus | [] | | selectra:blur | [] | | selectra:initialize | [] |

Plugins

Built-in Plugins

Activate plugins via the plugins config option:

selectra({
  plugins: ['remove_button', 'clear_button', { name: 'tag_limit', options: { tagLimit: 3 } }]
})

| Plugin | Description | |--------|-------------| | remove_button | Add × button to each selected tag | | clear_button | Add a clear-all button to the control | | restore_on_backspace | Restore deleted item text to input | | dropdown_header | Add a header to the dropdown | | tag_limit | Limit visible tags with "+N" badge | | auto_select_on_type | Auto-select first match on blur | | select_on_focus | Put current value into search on focus | | read_only | Make component read-only | | auto_position | Smart dropdown positioning (above/below) |

Custom Plugins

import { registerPlugin } from '@referralgps/selectra';

registerPlugin('my_plugin', function(options) {
  // `this` is the selectra component instance
  console.log('Plugin initialized with', options);

  // Override methods
  const originalOpen = this.open.bind(this);
  this.open = () => {
    console.log('Opening dropdown');
    originalOpen();
  };
});

Building

npm install
npm run build    # Build dist/
npm run dev      # Dev server with HMR
npm run test     # Run tests

Migration from jQuery Version

| jQuery Selectize | Selectra | |-----------------|---------------------| | $('select').selectize({...}) | x-data="selectra({...})" | | instance.addItem(val) | Direct method call in Alpine scope | | $.fn.selectize plugin | Alpine.plugin(Selectra) | | jQuery events | Custom DOM events | | LESS/SCSS themes | Tailwind CSS utilities | | Bootstrap themes | Use Tailwind directly |

License

Apache-2.0