Fuse.js Fuzzy Command Palette — Free JS Snippet

Fuse.js Fuzzy Command Palette · Navigation · Plain HTML, CSS & JS · Live preview

CategoryNavigation

What's included

Features

Fuzzy Bitap matching tolerant of typos and abbreviations
Weighted keys: name outranks keywords, which outrank section
ignoreLocation so matches anywhere in the title score fairly
Character-level highlighting from includeMatches with overlap merging
HTML-escaped output so command names can never inject markup
WAI-ARIA combobox and listbox roles with aria-activedescendant
Arrow-key, Enter and Escape handling plus mouse-hover sync
Grouped headings when idle, relevance-ranked list when searching

About this UI Snippet

Fuse.js Fuzzy Command Palette — HTML, CSS & JavaScript

Screenshot of the Fuse.js Fuzzy Command Palette snippet rendered live

A command palette lives or dies on its matching. If it only matches exact substrings, users must remember precisely how a command is worded, and the whole point — reaching a feature without hunting through menus — is lost. People type "tgl dark" for "Toggle dark mode" and "nw fle" for "New file"; a good palette understands them. Fuse.js is a lightweight fuzzy-search library that scores approximate matches with the Bitap algorithm, so abbreviations, dropped letters and typos still find the right command.

The configuration carries the design. keys accepts weights, so a hit in the command name counts three times as much as one in its keywords, and the section counts least; typing "night" finds "Toggle dark mode" through its keyword list but ranks below any command actually named for it. threshold controls tolerance — 0 requires a perfect match, 1 matches almost anything — and 0.4 is forgiving without returning noise. ignoreLocation is easy to miss and important here: by default Fuse penalises matches that occur far from the start of the string, which suits searching within a short field but ranks "Save all files" badly when you type "files". Turning it off matches anywhere in the string.

The highlighting works from includeMatches, which returns character index ranges for each matched key. Those ranges can overlap or touch, so the highlight function sorts and merges them before wrapping the pieces in mark elements, and escapes every fragment of text so a command name can never inject HTML. Showing which characters matched is what makes fuzzy results feel trustworthy rather than random.

The interaction follows the WAI-ARIA combobox pattern: the input has role="combobox" with aria-controls, the list is a listbox of options, and aria-activedescendant points at the highlighted item, so screen readers announce the selection while focus stays in the input. Arrow keys move the highlight, Enter runs it, Escape clears, the active row scrolls into view, and hovering also moves the highlight — mouse and keyboard stay in sync. Section headings appear only in the unfiltered list, because grouping breaks down once results are ranked by relevance.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Ask an AI assistant like Claude to add a global Ctrl+K shortcut with a modal overlay, remember recently run commands and rank them first, or support nested commands with a second-level menu.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a keyboard-driven command palette using Fuse.js 7 loaded from a CDN.

Requirements:
- Create a Fuse index over a list of commands with weighted keys (name 3, keywords 1, section 0.5), threshold 0.4, ignoreLocation: true, includeMatches: true and minMatchCharLength: 2.
- Highlight matched characters in the command name by merging the [start, end] ranges from the matches and escaping all text.
- Show section headings only when the search box is empty; otherwise show a relevance-ranked list with a result count.
- Implement the ARIA combobox pattern (role="combobox", listbox/option roles, aria-activedescendant), with ArrowUp/ArrowDown/Enter/Escape handling and mouse-hover sync.
- Running a command shows a confirmation message.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

Requires
<div class="fc-wrap">
  <div class="fc-box">
    <div class="fc-search">
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
      <input id="fcInput" type="text" placeholder="Type a command... try &quot;tgl dark&quot; or &quot;nw fle&quot;" autocomplete="off" role="combobox" aria-expanded="true" aria-controls="fcList" aria-autocomplete="list">
      <kbd>esc</kbd>
    </div>
    <ul class="fc-list" id="fcList" role="listbox"></ul>
    <div class="fc-foot"><span><kbd>&uarr;</kbd><kbd>&darr;</kbd> navigate</span><span><kbd>&crarr;</kbd> run</span><span id="fcCount"></span></div>
  </div>
  <div class="fc-toast" id="fcToast" role="status" aria-live="polite"></div>
</div>

Step by step

How to Use

  1. 1
    Browse the listWith the field empty, every command is shown grouped under File, View, Generate, Edit, Settings and Account.
  2. 2
    Type an abbreviationType "tgl dark" or "nw fle". Fuzzy matching finds Toggle dark mode and New file despite the missing letters.
  3. 3
    Search by synonymType "night" or "logout". Keywords surface the right command even though the words are not in its title.
  4. 4
    Navigate with the keyboardUse the up and down arrows to move, Enter to run a command, and Escape to clear the search.
  5. 5
    Watch the highlightingMatched characters are underlined in each result, showing why it was returned.

Real-world uses

Common Use Cases

App-wide command palette
Give power users a fast path to every action. For searching a product catalogue instead, see typo-tolerant product search.
ADMIN
Admin console quick-jump
Jump to any customer, setting or report by typing a fragment of its name.
Docs and knowledge-base search
Search articles by title and tags with forgiving, ranked results.
Learning fuzzy search tuning
Experiment with weights, threshold and location to see how each changes ranking.

Got questions?

Frequently Asked Questions

It sets how fuzzy matching is allowed to be: 0.0 requires a perfect match, 1.0 matches anything. Values around 0.3 to 0.4 suit most command lists.

By default Fuse scores matches near the start of a string higher. Disabling location makes a match anywhere in the text count equally.

includeMatches returns [start, end] index pairs for each matched key. The code merges overlapping ranges and wraps them in mark elements.

Add a keywords field to each command and include it in keys with a lower weight, so synonyms match without outranking title matches.

It uses the combobox and listbox roles with aria-activedescendant so the highlighted option is announced while focus stays in the input.

Fuse searches in memory and stays fast for a few thousand entries. For very large sets, pre-index on a server or use a dedicated search engine.

Yes. Use the JSX, Vue, Angular or Tailwind export buttons on this page to convert the markup and styles. The behaviour comes from Fuse.js, so in a framework project install it with npm install fuse.js instead of the CDN tag, build the index with useMemo / computed / a service, keyed on the data, and release it with nothing (it holds no DOM listeners) when the component unmounts.