I added a command palette to Codelit about three months ago. The users who find it stick around about 3x longer than the ones who don't.
Three times.
A command palette
is a keyboard-triggered search box that exposes every action in an application through one entry point, so a user types the name of a command instead of hunting for it in menus.
Now, some of that is selection bias: the people who go hunting for a ⌘K palette were probably always going to be power users. But it is the feature my stickiest users reach for most, it took a weekend to build, and I have never regretted it.
Why do power users want a command palette?
Power users want a command palette because it collapses every action in the product into one keystroke plus a few characters of typing, which beats any menu hierarchy. They hate menus. They know what they want to do, and they don't want to navigate three levels of dropdowns to do it.
Think about the tools you love using: VS Code, Figma, Linear, Raycast, Notion. They all have command palettes. It's not a coincidence.
For Codelit specifically, the problem was acute. You're working on an architecture diagram on an infinite React Flow canvas. You want to add a database node, switch to a different template, or export to Terraform. Without a command palette, that's: move mouse to toolbar, find the right section, click, find the subsection, click again. With the palette: press two keys, type "ter", hit enter. Done.
Three routes to the same action, and they are not equivalent:
| Route to an action | What it costs the user | Best for | Where it breaks |
|---|---|---|---|
| Nested menus | 4.2 seconds, average | The long tail nobody uses twice | Deep hierarchies hide the one thing you need |
| Command palette | 1.1 seconds, average | Anything you do occasionally | You have to roughly know what the action is called |
| Dedicated shortcut | One or two keys | The top ten actions by frequency | There are only so many keys, and nobody discovers them |
The stack: cmdk and a custom fuzzy matcher
Codelit's palette is built on cmdk by Paco Coursey, with its default filter swapped out for a fuzzy matcher I wrote. cmdk is a headless, composable command palette component for React: no opinions about styling, full keyboard navigation, and it handles the hard parts (focus management, scrolling, accessibility).
Here's the basic setup:
That's the skeleton. The real work is in what goes inside it.
What are the 28+ keyboard shortcuts in Codelit?
Codelit ships 28+ keyboard shortcuts in four groups: canvas editing, view controls, vim-style "go to" navigation, and global toggles. Every one is also reachable by name through the ⌘K palette, so nobody has to memorise the list below. I spent way too long deciding which keys map to which actions.
Canvas actions
| Shortcut | What it does |
|---|---|
| Ctrl+Z | Undo |
| Ctrl+Shift+Z | Redo |
| Ctrl+C | Copy selected nodes |
| Ctrl+V | Paste nodes |
| Delete / Backspace | Delete selected |
| Ctrl+A | Select all nodes |
| Ctrl+D | Duplicate selected |
| Ctrl+F | Find node on canvas |
| Ctrl+G | Group selected nodes |
View controls
| Shortcut | What it does |
|---|---|
| Ctrl+0 | Zoom to fit |
| Ctrl+= | Zoom in |
| Ctrl+- | Zoom out |
| Ctrl+1 | Zoom to 100% |
| M | Toggle minimap |
| L | Toggle layout direction (TB/LR) |
Navigation (vim-style "go to")
| Shortcut | What it does |
|---|---|
| G then T | Go to Templates |
| G then B | Go to Blog |
| G then F | Go to Features |
| G then P | Go to Pricing |
| G then H | Go to Home |
| G then S | Go to Settings |
Global
| Shortcut | What it does |
|---|---|
| Cmd+K / Ctrl+K | Open command palette |
| ? | Show keyboard shortcuts help |
| Escape | Close any modal/panel |
| N | New diagram |
| E | Toggle export panel |
| R | Toggle review panel |
| S | Toggle sidebar |
| T | Toggle theme (dark/light) |
The single-key toggles earn their keep once Codelit is installed as a standalone app, where there's no browser chrome around the window to fall back on.
How do you decide what gets a keyboard shortcut?
Give a dedicated key to any action users perform more than five times per session, and leave the rest to palette search. That was my rule. I tracked action frequency in Codelit for two weeks before building anything, and the data was clear.
- Undo/redo, by far the most common action (no surprise)
- Add node, second most common
- Delete node, third
- Zoom to fit, fourth (people lose their diagram on the infinite canvas constantly)
- Export, fifth
Everything in the top 10 got a single-key or two-key shortcut. Less frequent actions are accessible through the command palette search but don't have dedicated key bindings.
How does the palette know what to suggest?
Codelit's palette reads the app context before it renders and reorders itself around what you're doing. Open it with a node selected and node actions lead; open it on the templates page and template actions do.
| When you open it | What it leads with | Where that comes from |
|---|---|---|
| A node is selected | Edit label, Change type, Audit this node, Delete node | context.selectedNodes |
| You're on the canvas | Add database node, Add service node, Run architecture review, Export | context.currentPage === "canvas" |
| You're on the templates page | Use this template, Preview, Fork | the same page check |
| Any time | Your three most recent actions | context.recentActions |
The recent actions bit is key. If you exported to Terraform 5 minutes ago, "Export to Terraform" shows up at the top of the palette next time you open it. Small thing, big impact on perceived speed.
How do users find shortcuts they don't know exist?
Press ? anywhere in Codelit and you get a full keyboard shortcut reference, organised by category with visual key representations. Discoverability is the main problem with shortcuts — a binding nobody knows about is worth exactly as much as one that doesn't exist. I show a subtle tooltip about the ? modal during onboarding, too.
The palette results carry shortcut hints too. Each item shows its shortcut (if it has one) on the right side. So when someone uses the command palette to "Zoom to fit," they see Ctrl+0 next to it. Next time, they skip the palette and hit the shortcut directly.
This creates a natural learning curve: command palette first, discover shortcut, use shortcut directly. Users graduate from the palette organically.
Why I replaced cmdk's built-in filter
cmdk's default filter is an exact-substring match, which means typing "terra" won't match "Export to Terraform" if you're off by a character. I replaced it with a custom fuzzy matcher that scores four signals and lets near-misses through.
| Signal | Example | Effect on ranking |
|---|---|---|
| Exact prefix match | exp matches "Export" | Highest score, always ranks first |
| Consecutive character match | trrfrm matches "Terraform" | Survives dropped vowels and typos |
| Word boundary match | et matches "Export Terraform" | First letter of each word counts |
| Recency | anything you ran a minute ago | Score boost on top of text match |
The scoring weights are tuned so that exact matches always come first, but typos still find what you're looking for. I got the initial weights from Fuse.js's algorithm, then tweaked them based on actual user search patterns.
Terraform keeps turning up in these examples for a reason. Exporting a diagram to real Terraform and Kubernetes manifests was fifth on that frequency list, and it's a long enough word to be miserable to type.
What changed after three months
Three months in: users who use the palette run about 3x longer sessions, 40% of power users (10+ sessions) use shortcuts regularly, and average time to action dropped from 4.2 seconds with menu navigation to 1.1 seconds with the command palette.
Behind those headlines:
- "Zoom to fit" (Ctrl+0) is the most-used single shortcut in the product.
- The "every action reachable in under 2 seconds" goal holds for the top 30 actions.
- The long tail — things like "change edge animation speed" — still takes 3-4 seconds through nested menus, and those are rare enough that it doesn't matter.
Should you build one?
If your app has more than ~15 distinct actions, yes. Absolutely. Below that a menu is fine; above it, users stop being able to hold the whole product in their head.
The implementation cost is low. cmdk handles the hard parts. The maintenance cost is near-zero, since you add items to the palette as you add features. And the impact on power user retention is significant.
It's the best weekend I've spent on Codelit, and I've spent a lot of weekends on Codelit.
The users who bother to learn shortcuts are the same users who become your biggest advocates. Make their experience as fast as possible.
Try it at codelit.io. Press Cmd+K or ? and see for yourself.
Questions people actually ask
- What is a command palette in a web app?
- A command palette is a keyboard-triggered search box that exposes every action in an application through a single entry point. The user presses Command K or Control K, types a few characters of what they want, and hits enter. It replaces a trip through nested menus with one keystroke and a search query, which is why tools like VS Code, Figma, Linear and Notion all ship one.
- Which React library should I use to build a command palette?
- I used cmdk by Paco Coursey for Codelit's palette. It is a headless, composable React component, so it has no opinions about styling but handles the parts that are genuinely hard: focus management, scrolling the list as you arrow through it, and accessibility. I kept all of that and replaced only its default filter, which is a substring match, with a custom fuzzy matcher so near-miss typing still finds the right command.
- How do you decide which actions get a keyboard shortcut?
- My rule for Codelit is that any action users perform more than five times per session gets a dedicated shortcut, and everything else lives in the palette's search results. I tracked action frequency for two weeks before building anything. Undo and redo came first, then adding a node, deleting a node, zoom to fit, and export. The top ten actions by volume took the single-key and two-key bindings, and nothing else did.
- How do users discover keyboard shortcuts they do not know about?
- Discoverability is the main problem with keyboard shortcuts, because a binding nobody knows about is the same as a binding that does not exist. Codelit solves it three ways. Pressing the question mark key anywhere opens a full shortcut reference grouped by category. Onboarding shows a quiet tooltip pointing at it. And every result in the palette displays its own shortcut beside it, so people graduate from searching to pressing the key.
- Is a command palette worth building for a small SaaS product?
- If your product has more than roughly fifteen distinct actions, yes. Codelit's palette took a weekend to build because cmdk handles the difficult parts, and maintenance is close to zero because you add an entry when you add a feature. Average time to action fell from 4.2 seconds through menus to 1.1 seconds through the palette, and the users who adopt it run about three times longer sessions, though that last figure is correlation rather than proof.