# vue-multiselect: a Vue 3 select, multiselect and tagging component with no dependencies

> vue-multiselect is an MIT-licensed Vue component covering single select, multiple select, tagging and async search in one package. It is a good fit for Vue 3 apps that want a configurable dropdown without pulling in a UI framework, and a poor fit for anyone who needs a maintained Vue 2 upgrade path or a component that works without the Options API.

**shentao/vue-multiselect** — Universal select/multiselect/tagging component for Vue.js

- Repository: https://github.com/shentao/vue-multiselect
- Website: https://vue-multiselect.js.org/
- Stars: 6,781 · Forks: 986
- Language: JavaScript
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/shentao-vue-multiselect

## The gap vue-multiselect fills between a native select and a full UI kit

A native select element handles single choice and, with the multiple attribute, multiple choice. What it does not handle well is search inside the option list, free-text tagging, or options fetched from a server as the user types. Teams that need those behaviours usually pick one of two paths: adopt a component library, which brings a design system and a set of opinions along with the dropdown, or write the dropdown themselves, which means owning keyboard handling and filtering logic.

vue-multiselect sits between those paths. The README lists the feature set as single select, multiple select, tagging, dropdowns, filtering, search with suggestions, async options support and Vuex support, with no runtime dependencies. That last point matters for bundle budgeting: the package adds its own code and a stylesheet, not a dependency tree. The intended audience is a Vue 3 application that already has its own styling and only wants the select behaviour.

It is not a design system. The README points to a separate documentation site for anything beyond the props list, and the repository ships a dist stylesheet you import yourself. If you expect a themed, accessible-by-default widget with a documented focus contract, this is a lower-level tool than that.

## How the component is put together: mixins, v-model and the Options API

The README describes the logic as split into mixins, with a basic component plus support for custom components. That is the architectural claim the project makes about itself, and it is the reason customisation works the way it does: you can replace parts of the rendered output through slots and still keep the selection, filtering and keyboard behaviour from the mixins.

Data flow is standard Vue two-way binding. The component takes options through a prop and reports selection through v-model, or through :model-value plus @update:model-value in the examples that avoid v-model. When options are objects rather than strings, two props decide how they are read: label names the property shown to the user, and track-by names the property used to identify an option. Getting track-by wrong is the classic source of duplicated or unselectable entries, because the component needs a stable identity to compare against the current selection.

Async behaviour is event-driven. The component emits @search-change with the query, and your handler replaces the options array. The README example wires that to a findService(query) call and supplies a #noResult slot for the empty state. There is no built-in debounce, caching or request cancellation in that example; those belong to your handler.

The constraint that shapes everything else is stated plainly in the README: vue-multiselect requires Vue's Options API to function properly. The component is not written against the Composition API, and the README warns that some versions of @vitejs/plugin-vue can disable the Options API even when you did not configure that. That is a build-tooling dependency, not a component bug, but it lands on you.

## Installing vue-multiselect and wiring a first multiple select

The package installs from npm under the name vue-multiselect. The README gives the install command and a basic usage example, and the stylesheet is imported from the dist folder rather than from the package root.

```bash
npm install vue-multiselect
```

A minimal component registers VueMultiselect locally, holds a selected value and an options array in data, and renders the component with v-model and :options. The README's basic example uses a plain array of strings for options and a null starting selection.

```vue
<template>
  <div>
    <VueMultiselect
      v-model="selected"
      :options="options">
    </VueMultiselect>
  </div>
</template>

<script>
import VueMultiselect from 'vue-multiselect'
export default {
  components: { VueMultiselect },
  data () {
    return {
      selected: null,
      options: ['list', 'of', 'options']
    }
  }
}
</script>

<style src="vue-multiselect/dist/vue-multiselect.css"></style>
```

For multiple selection with search, the README adds three props to the same shape: :multiple="true", label and track-by. With object options, label decides the visible text and track-by decides identity.

```vue
<VueMultiselect
  v-model="multiValue"
  :options="source"
  :multiple="true"
  :close-on-select="true"
  placeholder="Pick some"
  label="name"
  track-by="name"
/>
```

Tagging reuses the same component with :taggable="true" and a @tag handler. The README's addTag example pushes a new object into both the options array and the selected array, which is what makes the new tag appear in the list and in the current value at once.

```javascript
addTag (newTag) {
  const tag = {
    name: newTag,
    code: newTag.substring(0, 2) + Math.floor((Math.random() * 10000000))
  }
  this.taggingOptions.push(tag)
  this.taggingSelected.push(tag)
},
```

If you hit unexplained breakage after a tooling upgrade, the README's own remedy is to pin the plugin down: npm install @vitejs/plugin-vue@5.2.1.

## The Options API requirement and the plugin-vue version trap

This is the limitation to understand before you commit, and it is unusual enough to state flatly. The README says the component requires Vue's Options API to function properly, and it links issue #1901 for the details. It then reports that updating @vitejs/plugin-vue to version 5.2.2 or later can cause problems, and suggests downgrading to 5.2.1.

Read that as a version ceiling on a build dependency, imposed by a UI component. If your project pins plugin-vue at 5.2.2 or newer, or if your team upgrades build tooling on a schedule, this component can become the reason you cannot. The README's explanation is that changes in the plugin's configuration handling can disable the Options API even when it was not explicitly configured, which means the failure is not something you opted into.

There is a second, quieter cost. The README directs readers to vue-multiselect.js.org for full documentation and otherwise shows props and slots by example. There is no rollback or migration guidance in the README for teams moving between major versions, and v4.0.0-alpha.0 sits alongside the stable 3.5.0 release. If you need a documented upgrade path with deprecation notices, that material is not in the repository's README.

Finally, Vue 2 users should not read this page as an upgrade route. Version 3 is the Vue 3 line, and the README frames it as documentation for version 3 compatible with Vue 3.

## Where vue-multiselect is the wrong tool

The component assumes Vue. That sounds obvious, but it eliminates React, Svelte and plain-DOM projects immediately, and there is no framework-agnostic build in the package files, which ship dist, src and index.d.ts.

It also assumes you want a dropdown. If your real requirement is a set of always-visible checkboxes, a native multiple select, or a chip input with no option list, you are paying for filtering, keyboard navigation and option rendering you will not use. The README's own feature list is a dropdown feature list.

Async search is another boundary. The README shows the pattern, not the implementation: your handler receives the query and replaces the options array, and the empty state is yours to fill through the #noResult slot. There is no documented debounce, no request cancellation and no loading indicator in the example. A search-as-you-type field hitting a slow endpoint needs that machinery, and you will write it.

And if accessibility conformance is a hard requirement with a documented audit trail, the README does not describe the component's ARIA behaviour or focus management. That is not evidence it is inaccessible; it is evidence the README does not make a claim you can cite.

## How it differs from Vueform/multiselect

The related searches around this project pair it with Vueform/multiselect, and the two take opposite approaches to the same problem. vue-multiselect is a standalone component: no runtime dependencies, a single stylesheet from dist, and configuration through props and slots. Vueform/multiselect is part of a form framework, which means the select arrives with the framework's conventions, its own styling system and its own configuration model.

The practical difference is what you inherit. Choosing vue-multiselect means you own the CSS and the surrounding form behaviour, and you get a small surface to learn. Choosing a framework-backed select means you get more built-in behaviour and a larger dependency to carry, plus an upgrade path tied to the framework rather than to the component. Neither is better in the abstract. If your app is a handful of forms, the standalone component is less to adopt. If you are standardising many form controls across a large application, the framework approach avoids rebuilding the same conventions repeatedly.

What the two share is the constraint that decides most evaluations: both are Vue 3 components, so neither helps a Vue 2 codebase.

## Maintenance, licensing and what an upgrade costs

The repository is not archived, and the last push was on 2026-09-17, which is recent. The release history shows v3.4.0 on 2025-10-06, v3.5.0 on 2026-03-17, and v4.0.0-alpha.0 on 2026-09-17. The stable line is 3.5.0, and package.json confirms that version. The alpha exists, but the README documents version 3.

Upgrade cost has two parts. The first is the plugin-vue ceiling described above: staying on this component may mean staying on @vitejs/plugin-vue@5.2.1. The second is the major-version question. A v4 alpha is published, and the README does not describe what changes between 3 and 4, so a team planning to track the component forward has nothing in the README to plan against. Budget for reading release notes and the linked issue tracker rather than the README.

Licensing is straightforward. The repository contains a LICENSE file and the project is MIT, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are preserved. The package also ships index.d.ts, so TypeScript consumers get types without a separate @types package. This is a description of the licence text, not legal advice; if your organisation has a licence review process, route the MIT terms through it.

## Conclusion

Adopt vue-multiselect if you are on Vue 3, want a single configurable dropdown component, and are willing to keep the Options API in play. Do not adopt it if you are still on Vue 2, if your build pipeline pins @vitejs/plugin-vue at 5.2.2 or later, or if you need a component whose internals are documented beyond the props list. Before committing, check your plugin-vue version, confirm the dist CSS import path resolves in your bundler, and read issue #1901 to judge whether the Options API constraint affects your setup.

## FAQ

### What is the difference between vue-multiselect and a plain dropdown?

A plain dropdown lets the user pick one value from a list. vue-multiselect covers single select but also multiple select, tagging and filtering, and it can fetch options asynchronously through the @search-change event. The README lists all of these as features of the same component.

### How do I select multiple options with vue-multiselect?

Set the multiple prop to true on the component and bind v-model to an array. With object options, the README's example also sets label and track-by so the component knows what to display and how to identify each option.

### Does vue-multiselect work with Vue 3?

Yes. The README is documentation for version 3, which it describes as compatible with Vue 3, and package.json lists version 3.5.0 as the current release. The README notes that v3 documentation is mostly the same as v2 because the component is largely backward compatible.

### Why does vue-multiselect break after I update @vitejs/plugin-vue?

The README states that the component requires Vue's Options API, and that changes in @vitejs/plugin-vue version 5.2.2 or later can disable the Options API even when it was not explicitly configured. The README's suggested workaround is to install @vitejs/plugin-vue@5.2.1, and it links issue #1901 for details.

### Does vue-multiselect have any dependencies?

The README lists NO dependencies as a feature, and the package is installed as a single npm package with a stylesheet you import from dist. Its devDependencies cover the build, lint and test tooling rather than runtime code.

## Sources

- [License: MIT](https://github.com/shentao/vue-multiselect/blob/master/LICENSE)
- [Project website](https://vue-multiselect.js.org/)
- [README](https://github.com/shentao/vue-multiselect/blob/master/README.md)
- [Releases](https://github.com/shentao/vue-multiselect/releases)
- [shentao/vue-multiselect on GitHub](https://github.com/shentao/vue-multiselect)

---

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