DEV Community

Devanshu Biswas
Devanshu Biswas

Posted on

I Rebuilt the Cmd-K Command Palette in ~60 Lines of JavaScript

Every great app has it now: hit ⌘K, a palette pops up, you fuzzy-type a few letters, hit Enter, done. Linear, Raycast, VS Code, GitHub. It feels like deep machinery — it's about 60 lines of vanilla JavaScript.

Try it live: https://dev48v.infy.uk/design/day10-command-palette.html

1. One global shortcut

The whole feature hinges on a single document-level listener. You MUST preventDefault — browsers bind Ctrl+K to their own search:

document.addEventListener("keydown", e => {
  if ((e.metaKey || e.ctrlKey) && e.key === "k") {
    e.preventDefault();
    openPalette();
  }
});
Enter fullscreen mode Exit fullscreen mode

2. Commands are data, not buttons

Every action becomes one object. The UI is generic — it lists objects and calls run() on the chosen one:

const COMMANDS = [
  { icon: "🌙", label: "Toggle dark mode", group: "Theme", run: toggleDark },
  { icon: "📄", label: "New file",         group: "File",  run: newFile },
];
Enter fullscreen mode Exit fullscreen mode

Adding a command is adding one line, never new markup.

3. Fuzzy matching feels like mind-reading

Palettes don't do substring match — they do subsequence match: the query's characters appear in order, not necessarily adjacent. So tgldk finds "Toggle dark mode":

function fuzzy(q, text) {
  let i = 0;
  for (const ch of text.toLowerCase()) if (ch === q[i]) i++;
  return i === q.length;   // all query chars found, in order
}
Enter fullscreen mode Exit fullscreen mode

A tiny loop with one pointer — and it's why you can fly through commands with sloppy half-typed queries.

4. Keyboard-first navigation

The point is to never touch the mouse. Up/Down move a selection index (modulo wraparound), Enter runs, Escape closes:

if (e.key === "ArrowDown") sel = (sel + 1) % shown.length;
if (e.key === "ArrowUp")   sel = (sel - 1 + shown.length) % shown.length;
if (e.key === "Enter")     { shown[sel].run(); close(); }
Enter fullscreen mode Exit fullscreen mode

5. Autofocus is the whole UX

The detail that makes it feel instant: focus the input the moment it opens, so the user types immediately — no click:

overlay.show();
input.focus();
Enter fullscreen mode Exit fullscreen mode

The takeaway

Global shortcut + command data + fuzzy filter + autofocus. That's the entire command palette. Build it once and you understand the interaction pattern behind half of modern power-user tooling. Open the demo and press ⌘K.

Top comments (0)