A blazing-fast, GPU-accelerated launcher and script engine for macOS. Built with Rust & GPUI for zero-lag performance and dynamic UI layouts.
Features • Installation • Widgets & Theming • Interactive Scripts • Shortcuts
demo.mp4
Recorded demo showing instant search, theming with custom theme_switcher script, clipboard manager script, and native file search plugin
Aerofi is a modern modal launcher designed for speed-obsessed macOS users. It bridges the gap between lightweight Unix dmenu/rofi tools and feature-rich productivity shells like Raycast, giving you rich UI components with zero configuration bloat.
- Pure Rust + GPUI rendering on Metal: instant cold starts, zero-lag typing, 120 FPS — no Electron, no WebViews
- 25–35 MB memory footprint
- Six execution modes:
silent,compact,inline,fullOutput,pipe, and interactiverofi - Two-way stdin/stdout IPC: live lists, keyboard events, markdown previews — no SDKs, any language
- Drop-in compatibility with Raycast Script Commands
- Declarative widget engine (custom headers, footers, action buttons, status pills)
- TOML theming:
$palettetokens, frosted glass blur, fonts, modularimportsto mix palettes and layouts - Dynamic Window Shell — the window resizes itself to fit the active preset
- Native C ABI plugins (docs, Rust/C/C++/Swift)
- Fuzzy / prefix / glob matching, frecency or lexical ranking, pinned items
- Global hotkeys via the Carbon API — no Accessibility permissions
- GitHub Flavored Markdown rendering inside the launcher
- Multi-select with
Tab, hover-to-select, clickable rows, instant live updates
| Feature | Rofi / dmenu | Alfred | Raycast | Aerofi |
|---|---|---|---|---|
| Platform | Linux (X11/Wayland) | macOS | macOS | macOS |
| Engine & Speed | C / C++ (CPU Render) | Objective-C / AppKit (Native) | React / Node.js (Heavy SDK) | Rust + GPUI Metal (Zero-Lag) |
| Configuration | Complex RASI / CSS | Closed GUI / Preferences | Closed GUI / App Settings | Clean TOML Design Tokens |
| Scripting Model | One-shot stdout | JSON stdout / Scripts | Heavy TS / React Extensions | Two-way IPC Protocol (No SDKs) |
| Window Geometry | Static window size | Fixed bar + dropdown | Fixed app frame | Dynamic Window Shell (Adapts to preset) |
| Memory (idle) | ~10–40 MB | 50–90 MB | 250+ MB | 25–35 MB |
| macOS Permissions | None (Linux) | Accessibility | Accessibility + Screen Recording | None (Carbon hotkeys) |
Aerofi is designed to act as the Unix-style orchestrator for your custom macOS setup without requiring heavy background daemons:
- AeroSpace / yabai: Pipe
aerospace list-windowsinto Aerofi for an instant, blurred window switcher. - Native Carbon Hotkeys: Binds global shortcuts directly via Carbon API — no
skhdor invasive Accessibility permissions required. - Ecosystem Sync: Trigger scripts that update your Aerofi TOML palette while reloading SketchyBar, Ghostty, and Jankyborders simultaneously.
Install aerofi and start it as a native macOS background service:
brew install frostymur/tap/aerofi
# Start as a background service (starts automatically at login)
brew services start aerofibrew upgrade aerofi picks up new releases.
Download the latest prebuilt binary from GitHub Releases:
- Apple Silicon (M1–M6):
aerofi-mac-arm64.tar.gz - Intel Mac (x86_64):
aerofi-mac-x86_64.tar.gz
Unpack and place in your $PATH (e.g. /usr/local/bin or ~/.local/bin):
# Example for Apple Silicon:
curl -L -o aerofi.tar.gz https://github.com/frostymur/aerofi/releases/latest/download/aerofi-mac-arm64.tar.gz
tar -xzf aerofi.tar.gz
sudo mv aerofi /usr/local/bin/
# Run aerofi:
aerofi &
# Check the version (instant, no window):
aerofi --versioncargo install --git https://github.com/frostymur/aerofi aerofigit clone https://github.com/frostymur/aerofi
cd aerofi
cargo build --release
./target/release/aerofiaerofi is completely customizable via transparent, human-readable TOML files in ~/.config/aerofi/:
- Declarative Widget System: Compose custom headers, footers, status pills, and action strips directly in
theme.tomlusingbox,text,icon,image,spacer,divider, andbuttonwidgets. - Layout Control: Freely rearrange the UI hierarchy in
[mainbox](e.g. place widgets aboveInputBar, between elements, or belowListView). - macOS Glassmorphism: Native translucent frosted glass blur, opacity, border radii, shadows, and reusable
$palettecolor tokens.
# Example: Adding a custom header and action footer in theme.toml
[mainbox]
children = ["header_bar", "InputBar", "ListView", "footer_bar"]
[widgets.header_bar]
type = "box"
orientation = "horizontal"
gap = 8.0
children = ["header_title", "spacer", "status_badge"]
[widgets.header_title]
type = "text"
text = "aerofi"
color = "$accent"
font_weight = "bold"The built-in Dark Transparent theme is always available. Additional curated
themes ship in examples/themes/ — copy any of them to
~/.config/aerofi/themes/ and select it with theme = "<name>":
| Theme | Description |
|---|---|
| Tokyo Night | Deep indigo surfaces with neon cyan & sky blue accents and frosted glass blur. |
| Tokyo Night Grid | Compact 4-column grid layout with larger application icons. |
| Catppuccin Mocha | The Catppuccin Mocha palette in a transparent split two-pane layout. |
| Gruvbox Dark | Warm vintage retro-groove palette with high contrast and earthy tones. |
| Graphite Mono | Minimal strictly-monochrome graphite palette in a split layout. |
Themes support modular splitting via imports = ["colors/...", "layouts/..."] to effortlessly mix-and-match color palettes and window layouts.
Read the Customization Guide and explore
examples/themes/for complete references.
Turn any Bash, Python, Node.js, or Swift script into a dynamic macOS mini-app with @aerofi.mode rofi:
- Bidirectional Streaming: Your script outputs items via
stdoutand receives keyboard events (Enter,Tab,Ctrl+D, custom keys) viastdinin real-time. - Pango Markup Formatting: Full support for rich colors, bold text, and badges (
<span foreground="#7aa2f7" weight="bold">Title</span>). - Multi-Selection & Actions: Interactive multi-select with
Tab, batch deletion withCtrl+D, and custom keybindings. - Instant Live Updates: Update lists, badges, and search prompts dynamically without restarting the script.
#!/usr/bin/env bash
# @aerofi.title Theme Switcher
# @aerofi.mode rofi
# @aerofi.icon 🎨
echo -e "\0prompt\x1fSelect a theme:\n\0markup-rows\x1ftrue\n\0flush"
echo -e "<b>Tokyo Night</b>\0icon\x1femoji:🌃\0info\x1fActive"
echo -e "<b>Gruvbox Dark</b>\0icon\x1femoji:🌲\0info\x1fCommunity"Real-world scripts available in examples/scripts/:
clipboard.py— Interactive clipboard manager with syntax highlighting, multi-select (Tab), and item deletion (Ctrl+D)theme_switcher.py— Interactive Rofi theme previewer with live swatches and instant config updatingfull-output.sh— Markdown viewer rendering formatted GitHub Flavored Markdown inside the launchercompact.sh— Progress tracking with non-blocking floating toast status indicatorssilent.sh— Background automation with completion notification toasts
Copy any script to ~/.config/aerofi/scripts/ to use it immediately.
Tip
Migrating from Raycast? Aerofi offers drop-in compatibility with hundreds of open-source Raycast Script Commands. Just drop your existing .sh or .py files into ~/.config/aerofi/scripts/.
Read the Scripting & Rofi Protocol Guide and the Multi-Step Guide, and check out
examples/scripts/for working implementations.
aerofi keeps rofi's Unix philosophy — the same stdin/stdout piping model
(rofi script mode), so community scripts port with minimal changes — but
runs natively on macOS instead of through a Linux translation stack:
- Linux rofi under XQuartz costs 200 MB+ RAM, breaks Retina scaling, lacks window blur, and drains the battery; aerofi renders natively on Metal at 120 FPS
- Global hotkeys come from the Carbon API — no Accessibility permissions required (Raycast and Alfred both need them)
| Shortcut | Context | Action |
|---|---|---|
Option+Space |
Global | Toggle aerofi launcher window |
↑ / ↓ (or Ctrl+P / Ctrl+N) |
Launcher | Navigate result list |
Enter |
Launcher | Launch item (activates a running app) |
Shift+Enter |
Launcher | Open a new window of a running app (AppleScript, open -n fallback) |
Cmd+R |
Launcher | Reload configuration and rescan sources |
Cmd+. |
Launcher | Cycle runtime mode ([modes] + loaded plugins): All → each mode → each plugin → All |
Escape |
Launcher | Close aerofi window / Clear search |
Tab |
Rofi Mode | Toggle multi-selection checkbox |
Ctrl+D |
Rofi Mode | Secondary action (e.g. delete item) |
Launching applications. Enter (or clicking a row) activates an app that is
already running, matching macOS open. Press Shift+Enter to open a new
window: aerofi first asks the app itself via AppleScript (make new window,
same process — no duplicate instance), and falls back to open -n for apps
without a scripting dictionary (e.g. Chrome). This is handy for apps like
Terminal or Finder when you want a second window. Set
[general] new_instance_mode = "force" to always use open -n, or
"background" to use open -n -g (window lands on the current workspace
without activating the app).
Filtering sources at runtime. Define named source filters in
[modes] (e.g. scripts = "scripts,builtins") and cycle them with
Cmd+. or theme buttons using action = "mode:<name>" — the active mode
shows as a badge in the input bar. Any loaded plugin name is also a mode:
its session opens with the prefix applied and hidden, so the input box
holds only your query. Useful for script-heavy setups instead of
hand-editing [sources]. See Customization — Runtime Source
Filters.
- Documentation: docs/ — config schema, scripting & Rofi protocol, multi-step guides, and plugin development
- Examples: examples/scripts/ for working scripts
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Got a custom theme or an awesome IPC script?
We welcome contributions! See CONTRIBUTING.md for guidelines.
MIT — See LICENSE
- Built on GPUI — the GPU-accelerated UI framework from Zed
- Inspired by rofi
- Drop-in compatibility with community script-commands