Launch apps
Type a few letters — saf → Safari. Freshly-installed apps get boosted so
they’re easy to find right after install.
Pounce is a free, open-source, native command palette for macOS — a fast, dmenu-style picker you summon with a hotkey. Hit ⌘Space, fuzzy-type, hit Return. It launches apps, runs commands, answers quick questions inline, and hosts a handful of built-in modes (clipboard, emoji, screenshots, and more).
Its whole personality is one idea: every command is a file. Drop a shell script in a folder and it’s in the palette — no plugin API, no extension store, no account.
It’s MIT licensed and free — every feature on this page, no paid tier.
hotkey object
takes a key and modifiers.Launch apps
Type a few letters — saf → Safari. Freshly-installed apps get boosted so
they’re easy to find right after install.
Run commands
Your scripts and the built-ins appear alongside apps, ranked by how often you use them.
Clipboard history
Browse and restore recent copies in a two-pane view; optionally auto-paste into the app you came from.
Find Files
Search files and folders by name as you type, over Spotlight’s index. ⏎ opens, ⌘⏎ reveals in Finder, ⌥⏎ copies the path.
Quick answers
Math, unit, time-zone, and currency queries answer inline as a pinned first
row — ⏎ copies the result.
Emoji, screenshots, more
Built-in modes for an emoji grid, a screenshot browser, a camera peek, and a searchable cheatsheet.
| Key | Action |
|---|---|
| Type | Fuzzy-search in real time |
↑ / ↓ | Move the selection |
Return | Run the default action |
⇧Return | Insert a newline — the query field is multi-line |
⌘Return | The modifier action (often “Reveal in Finder” for apps) |
⌥Return / ⌃Return | Alternate actions, when shown |
Tab | Cycle sections (or emoji categories) |
Esc | Dismiss |
The action bar at the bottom always shows which modifiers do what for the selected row, so you don’t have to memorize them.
Results are ordered by a blend of three signals, so the thing you want is usually already on top:
Some queries are answered in the palette instead of being fuzzy-matched
against apps and commands. The answer pins to the top as its own row, and
Return copies it:
| Type | Get |
|---|---|
2*847, 2^10, sqrt(9), round(2pi) | Arithmetic, with the interpretation shown beside it |
100 + 10%, 20% of 150 | Percentages |
72 f in c, 1 pound in kg, 10 km in mi, 1 gib in mib | Unit conversion |
100 usd in eur, $100 in eur, 50 euros in yen | Currency conversion |
14:00 utc in pst, 2pm utc in tokyo, 9pm pst in utc | Time-zone conversion |
There’s no trigger prefix — a query that no engine can parse just falls through
to the normal results, and anything without a digit skips the engines entirely
(so safari and 1password stay searches). Output follows your locale, so
1/4 copies 0,25 on a German Mac.
Currency uses the European Central Bank’s daily reference rates (fetched from
api.frankfurter.app, refreshed at most every 12 hours, cached to
~/.local/share/pounce/currency-rates.json so it keeps answering offline). It’s
the only network request Pounce makes; set quickAnswers.currency to false in
config to switch it off entirely. Nothing about
your usage is ever sent anywhere.
Pounce ships an MRU window switcher: tap the chord to bounce to your last window, hold it and keep tapping to walk older ones, or type while holding to fuzzy-filter. It moves by window, not by app, so two Ghostty windows are two rows.
It’s off by default because it needs the Accessibility grant to install an
event tap. Turn it on with the windows block in
config (or
nebelhaus.pounce.windowSwitcher
in the rice, where it defaults on). If you run AeroSpace, rows carry the
window’s workspace and focusing goes through aerospace focus --window-id so a
window parked elsewhere surfaces properly; without it, everything degrades to
plain focus.
Some commands open a second picker instead of acting immediately — “Brew
Services” lists services, “Force Quit” lists processes. Pounce swaps the list in place with
no window flicker. Any command you write can do this by declaring
# pounce: submenu = true. See Writing pounce commands.
Out of the box you get: Activity Monitor, Brew Services, Camera, Capitalize, Clipboard History, Emoji, Find Files, Force Quit, Lock Screen, Lowercase, Ports, Report Issue, Screenshots, System Settings, and (Homebrew installs) Update Pounce. Each is just a script you can read, copy, or replace.
Capitalize and Lowercase rewrite the text you have selected in any app
— they copy the selection, run it through a one-line shell filter, and paste it
back via pounce --transform. Swap tr for anything and you have your own text
action.
Update Pounce self-updates in place, and what it does follows how you
installed Pounce: a Homebrew build runs brew upgrade pounce and restarts the
service; a copy dragged to /Applications downloads the new release and swaps
itself out; a Nix or rice install is pointed at the flake (haus update) rather
than overwritten, since the next rebuild would revert it. It runs in the
background and reports via notifications — see the Pounce
reference for the full per-install breakdown.
Every System Settings pane is its own command too, so typing “Displays” or “Accessibility” jumps straight there instead of dropping you at the front door.
Report Issue opens a pre-filled GitHub issue with your pounce and macOS versions already in the body — the rice ships a matching one for nebelhaus itself.
Beyond the built-ins there’s a shelf of optional plugins, off by default because each one assumes a specific tool, service, or app on your machine:
| Plugin | What it does | Needs |
|---|---|---|
| Audio Devices | Switch sound output & input from the palette | brew install switchaudio-osx |
| Bluetooth | Connect & disconnect paired devices (AirPods, keyboards, …) | brew install blueutil |
| Caffeinate | Keep the Mac awake — indefinitely or on a 30m/1h/2h timer | nothing (system caffeinate) |
| Docker | Start, stop, restart & tail logs of containers; offers to start the engine | any engine that answers docker ps (Docker Desktop, OrbStack, colima) |
| GitHub | Jump to your PRs, review requests, issues & repos in the browser | gh CLI, authenticated |
| Spotify | Playback controls: play/pause, next, shuffle, now-playing | Spotify.app (drives it over AppleScript) |
| SSH Hosts | Pick a host from ~/.ssh/config (Includes too); ⏎ connects, ⌘⏎ copies the command | hosts in ~/.ssh/config |
| Tailscale | Connect/disconnect, copy your tailnet IP or any peer’s | tailscale CLI (ships inside Tailscale.app) |
On Nix, enable them by id when consuming the pounce-commands package:
pounce-commands.override { plugins = [ "docker" "ssh" "tailscale" ]; }An enabled plugin behaves exactly like a built-in — same palette discovery, same
pounce-<id> bin for hotkey bindings, still shadowable from your user dir. Not
on Nix? Every plugin is still just one script: copy it from
pkgs/pounce-commands/optional/
into ~/.config/pounce/commands/ and it’s live on the next ⌘Space.
brew tap nebelhaus/tapbrew install pouncebrew services start pounce # start the daemonpounce --request-accessibility # one-time, for paste-back featuresThe formula installs a prebuilt Pounce.app signed with our Apple Developer
ID and notarized by Apple — it opens straight away, no Gatekeeper prompt
and no compile step. Requires macOS 14 Sonoma or later on Apple Silicon; the
release is arm64 only.
Because that signing identity is stable, the Accessibility grant survives
brew upgrade — you approve it once, not once per release.
Or with Nix: nix run github:nebelhaus/pounce -- --help.
Clipboard auto-paste and emoji paste synthesize a ⌘V into your previous app, which macOS gates behind Accessibility:
pounce --request-accessibility # approve the dialogpounce --check-accessibility # prints true when grantedFull configuration, CLI flags, and file paths are on the Pounce config & CLI reference. To extend it, head to Writing pounce commands.