Open-source project
Magicsuggest/magicsuggest avatar
Magicsuggest/magicsuggest

MagicSuggest is a Bootstrap 3 multi-select autocomplete with a long feature list and a slow release cadence

Multiple Selection Combo Box using Bootstrap

1,282 stars258 forksJavaScriptLicense varies

At a glance

What is it?
MagicSuggest is an MIT licensed jQuery plugin that turns a text input into a multiple selection combo box with suggestions, tags and remote search, distributed on npm and through bower and composer. Its last release, 2.1.7, swapped deprecated jQuery methods for native JavaScript, and the package still declares a hard Bootstrap 3 dependency.
Who is it for?
MagicSuggest fits a team maintaining an existing Bootstrap 3 and jQuery application that needs a multi-select with type-ahead, and the released code is the maintained one, with 2.1.7 removing the deprecated jQuery calls that would break on a modern jQuery. It does not fit a new project, since a Bootstrap 3 and jQuery 1.8 dependency is a hard constraint and both are long past end of life, and it does not fit a modern framework build that has dropped jQuery.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A plugin with a very long changelog in the README

MagicSuggest describes itself as a multiple selection auto-suggest input box for Bootstrap, and the package.json narrows that to a multiple selection auto-suggest input box for Bootstrap 3.

The README is not a normal README. It is a milestone changelog, going back through v1.2.0 in March 2013, v1.3.0 in May 2013, v1.3.1 in August 2013 and v2.0.0, with each entry credited to the contributor who made the change. That is an unusual and honest artefact for a plugin, and reading it tells you what the component actually does better than any marketing copy would.

The v1.3.0 and v1.3.1 entries are a list of the behaviours that a multi-select has to get right. The combo component can be fetched through the same div element. A value specified in the DOM original element is passed correctly to the component. The component's config can be set up entirely from the DOM container element. MagicSuggest can be rendered from a select DOM component. The space taken for a single selection on a small combo remains on one line. The input space now always uses the remaining space, as this leads to less issues. And the CSS is fixed so it behaves correctly within a Bootstrap modal.

That last one is the kind of detail you only learn from a bug report, and the modal case is a good example of why a component built on another component's layout needs its own tests.

The v1.3.0 list also shows the features that define the component. Multiple items can be selected through the Ctrl key. cfg(data) can take a function as parameter, or a json object whose data items are within the results property. There is a silent mode on the selection changing methods so you can know if a change was user-triggered. There is a setData(object) method to fill the combo after it has been rendered. There is cfg(strictSuggest) so the user can choose how the suggestions are made, and cfg(toggleOnClick) so the user can expand or close the combo by clicking on it. And there is a selectionRenderer configuration, which is what lets the appearance of a selected item be customised.

The v1.2.0 entry names the change that made the whole thing possible, standardization on jQuery plugins.

The 2.0 line tied it to Bootstrap 3 and moved the docs

MagicSuggest 2.0.0 is described with a new home, a URL for the project, and the README says it includes a great new API documentation, examples, tutorials and more.

The reason for the move is stated in the milestone list. The new home is to run dynamic examples that gh-pages couldn't handle, which is a very specific constraint, GitHub Pages could not run the interactive examples the way the new site does.

And then the substantive change for users. Now runs with Bootstrap 3 (required). Responsive design. No more intrusive loading.

The word required on Bootstrap 3 is the important one. The package.json declares the dependency as bootstrap at ~3, so it is a hard dependency rather than a peer dependency, and the plugin's CSS and markup are written against Bootstrap 3's grid and component classes. A team on Bootstrap 4 or 5 cannot use this without porting the markup.

There is a related dependency note in the v1.3.0 list, a minimum jQuery version was added to work in the docs, and the package.json declares jquery at >= 1.8.3. So the floor is jQuery 1.8.3.

The plugin also has a security fix in its history that is worth knowing about. The v2.1.6 entry is a single line: (fix) Disabled arbitrary HTML and SCRIPT execution on input. That is a cross site scripting fix in a component that renders user-typed text into the DOM, and it is the reason a 2.1.6 or later version matters if you adopt this at all.

The v2.1.5 entry is smaller. The close button is prepended instead of appended, the minified file is updated with current master code, and there is a feature to dynamically update the max selection size, which is the kind of thing you need when a form's limit depends on a server-side rule.

The 2.1.7 release is a jQuery deprecation sweep

The most recent release is described in the README as an update to deprecated jQuery methods, and the three bullets are the whole change.

- (fix) updates deprecated jQuery methods such as trim(), $.isArray, and Proxy(). - (Update) It replaces them with native JavaScript alternatives. - (Fix) the jQuery method each() is also replaced with native JavaScript forEach() - where possible.

The significance is not that the plugin stopped using jQuery, it still depends on jquery at >= 1.8.3, it is that it stopped using the jQuery functions that jQuery itself deprecated. trim(), $.isArray and $.isFunction were removed from jQuery in version 4, and a plugin calling them breaks hard on a modern jQuery rather than failing gracefully. The where possible in the each() line is a nice detail, since each() and forEach() differ in argument order and in how they handle the this binding, so some call sites cannot be converted mechanically.

The release that followed the 2.1.6 security fix, and the release before the current master state, is 2.1.7 on 2024-03-30. Before that came v2.1.6 on 2020-11-05 and v2.1.5 on 2020-10-30. So the recent history is two releases a week apart in late 2020, then a gap of more than three years, then one release in 2024.

The last push to master was on 2026-04-02, so the branch is being touched, but the pattern is clear. This is a mature component in maintenance mode, where the changes are compatibility fixes rather than features.

Three package managers and a one file build

The distribution story is the second half of the README, and it is a snapshot of how plugins were shipped in that period.

The top level listing shows a bower.json and a composer.json alongside the package.json, plus a magicsuggest.jquery.json, which is the jQuery plugin manifest format. So the component was published to npm, to bower, to Packagist through Composer, and registered as a jQuery plugin. Four channels for one JavaScript file.

The build is trivially simple, which is appropriate for a single-file plugin.

json
"scripts": {
  "set-version": "cross-var \"replace-in-file @VERSION@ $npm_package_version ./magicsuggest.min.js\"",
  "compressjs": "uglifyjs ./magicsuggest.js -c --comments --source-map \"root='/', url='magicsuggest.min.js.map'\" -o ./magicsuggest.min.js",
  "postcompressjs": "npm run set-version",
  "build": "npm run compressjs"
}

So the source is magicsuggest.js, the build runs uglifyjs with compression and comments preserved and a source map, and then a postcompress step replaces a @VERSION@ placeholder in the minified file with the package version using cross-var and replace-in-file.

That last step is a period detail worth noticing. It exists because a minified file cannot read the version from package.json at runtime in a browser, so the version is baked in as a string at build time. The minified file therefore differs from what uglifyjs produced, which is why the set-version step runs after compression rather than before.

The dev dependencies are correspondingly minimal, cross-var, replace-in-file and uglify-js at ^3.17.4, which is a recent version of uglify, so the build tool has been kept current even though the plugin itself has not gained features.

Where MagicSuggest is the wrong choice

The first wrong case is a new project. The dependency floor is Bootstrap 3 and jQuery 1.8.3, and both are long past end of life. A team starting fresh in 2026 will pick Bootstrap 5 or Tailwind, and will not be using jQuery at all, so this plugin requires you to adopt a stack that is a decade old to get one component.

The second wrong case is a modern framework build. The pattern of a jQuery plugin initialised on a DOM element is fundamentally at odds with a component model that owns its own DOM, and a React or Vue application that has removed jQuery cannot include this without pulling jQuery back in for one widget.

The third wrong case is a large tag set. The component keeps its selected items as tokens in the input, and the v1.3.0 list shows the layout work involved, input space always using the remaining space, the space taken for a single selection on a small combo remaining on one line. Those are hints that the input is an input with tokens in it, and the constraints of a text input are the constraints of the component. A multi-select with hundreds of selected values is a different widget, usually a list with checkboxes and a search field, and MagicSuggest is not that.

The fourth wrong case is a team that expects an actively developed component. The last release is 2.1.7 from 2024-03-30 and the last push to master was on 2026-04-02. The changes in the recent history are compatibility fixes, and the 2.0.0 milestone shows that the last time there was a significant feature push was years ago.

How it differs from a select multiple with a search field

The comparison worth making is with the alternative that most teams would build, a styled multiple select with a separate search input, and the difference in approach is that MagicSuggest hides a native control.

A multiple select is a native element. It has keyboard behaviour, screen reader support, form submission, and the platform's own interaction model, all for free. What it lacks is filtering, which is why people replace it with something that looks like a text input with tags.

MagicSuggest takes the second route. The user types, a suggestion list appears, and selecting a suggestion creates a token in the input. The advantage is that the filtering is the same interaction as any autocomplete, and the disadvantage is that you lose the native control's accessibility, its keyboard behaviour and its form semantics, all of which have to be rebuilt.

The second difference is where the data comes from. The configuration takes a data function, a data object with a results property, or a setData call after rendering, and the v1.3.0 list records a fix for the ajax query being sent twice when the user was typing faster than the typeDelay. So there is a remote search mode with debouncing, and the component can also be filled from a local array or from a select element already on the page.

The third difference is the configurability, and it cuts both ways. strictSuggest controls whether a typed value that is not a suggestion is allowed, selectionRenderer controls how a selected item looks, and a silent mode distinguishes a user-driven change from a programmatic one. That is a rich surface, and it is the same rich surface that makes the component's behaviour hard to predict unless you read the documentation for each option, which is why the milestone changelog is genuinely the best documentation source.

Editorial conclusion

MagicSuggest fits a team maintaining an existing Bootstrap 3 and jQuery application that needs a multi-select with type-ahead, and the released code is the maintained one, with 2.1.7 removing the deprecated jQuery calls that would break on a modern jQuery. It does not fit a new project, since a Bootstrap 3 and jQuery 1.8 dependency is a hard constraint and both are long past end of life, and it does not fit a modern framework build that has dropped jQuery. Before adopting it, read the feature list in the README carefully, because the configuration surface is large and the component behaves differently in a modal or with a single selection, and note that the last push to master was on 2026-04-02 with 2.1.7 released on 2024-03-30.

Frequently asked questions

What does MagicSuggest do and what does it require?

It is a multiple selection auto-suggest input box, a jQuery plugin that turns a text input into a combo box with suggestions and selectable tags. The package.json declares bootstrap at ~3, required, and jquery at >= 1.8.3, and the 2.0.0 milestone brought Bootstrap 3 support, responsive design and the removal of intrusive loading.

How do I build MagicSuggest from source?

Run npm run build, which runs the compressjs script invoking uglifyjs on magicsuggest.js with compression, preserved comments and a source map, producing magicsuggest.min.js. A postcompress step then replaces the @VERSION@ placeholder in the minified file with the package version, using cross-var and replace-in-file.

What changed in MagicSuggest 2.1.7?

It updates deprecated jQuery methods such as trim(), $.isArray and Proxy() to native JavaScript alternatives, and replaces the jQuery each() with native forEach() where possible. The previous release, 2.1.6, disabled arbitrary HTML and SCRIPT execution on input, which is the XSS fix.

How is MagicSuggest distributed?

Through four channels. The repository ships a package.json for npm, a bower.json for bower, a composer.json for Packagist, and a magicsuggest.jquery.json manifest for the jQuery plugin registry, alongside the magicsuggest.js source and magicsuggest.css stylesheet.

What configuration options does MagicSuggest support?

The README milestone list records cfg(data) taking a function or a json object with a results property, a resultsField for custom result property, cfg(strictSuggest) to control how suggestions are made, cfg(toggleOnClick) to expand or close the combo on click, a selectionRenderer for the appearance of selected items, and a silent mode on the selection changing methods so you can tell a user-triggered change from a programmatic one.

Official sources

  1. Issues
  2. Magicsuggest/magicsuggest on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/magicsuggest-magicsuggest.svg)](https://hysenlabs.com/projects/magicsuggest-magicsuggest)

Was this useful?