Skip to content

Custom Entries

Custom entries are optional. Raffi already lists your installed applications and its addons; an entry adds something it can’t find by itself, such as an app opened with particular arguments, a command, or an inline script. Entries live in ~/.config/raffi/launchers.yaml, where each top-level key is an entry. They can also go under a launchers: key in raffi.yaml, see Configuration Files.

Once you have entries, installed apps are only listed next to them when addons.apps.enabled is true. Apps that an entry already covers are left out.

Each entry is identified by a unique key and contains configuration fields:

launchers.yaml
firefox:
binary: firefox
args: [--marionette]
icon: firefox
description: Firefox browser with marionette enabled

binary string (optional)

Executable name looked up in PATH. Examples: firefox, kitty.

If the binary doesn’t exist in PATH, the entry is automatically hidden.

For scripts, this field specifies the interpreter (defaults to bash if omitted).

description string

Label shown in the launcher.

If binary is not specified, description is used as the binary name, except for alias entries.

args array

Command-line arguments passed to the binary.

Supports path expansion (~/ and ${VAR}).

env map of strings

Environment variables set for the binary or script, on top of the ones Raffi runs with. Values support ~/ and ${VAR} expansion, so PATH: "~/bin:${PATH}" prepends a directory.

When Raffi starts the program through the compositor (general.launch), or prints it with --print-only, the command line starts with env -- NAME=value ... so the variables still apply. The values show up in the preview pane and in --print-only output, so keep secrets out of them.

The variables reach the program Raffi starts, not programs it asks the compositor to start. A run-or-raise wrapper that launches the app through hyprctl, niri msg or swaymsg gets them, but the app does not; put env NAME=value in the wrapper’s own command instead.

launchers.yaml
firefox-work:
binary: firefox
args: ["-P", "work"]
description: "Firefox (work)"
env:
MOZ_ENABLE_WAYLAND: "1"
TZ: Europe/Paris

env cannot be combined with alias; such entries are skipped with a warning, as are entries with an empty variable name or one containing =.

icon string

Icon name from system theme (e.g., firefox, terminal).

Raffi looks up the icon by name from system icon directories. See Icons for details on icon discovery and caching.

script string

Inline script content. When present, the entry executes this script instead of launching binary directly.

See Scripts for details.

disabled boolean (default: false)

When true, hides the entry from the launcher.

show_preview boolean (default: false)

When true, Raffi shows the right-hand preview pane for this entry (full command or script, conditions, launch stats) even when general.show_preview is unset or false. Set to false to never preview it.

close_on_action boolean (default: general.close_on_action, else true)

Whether Raffi closes after launching this entry. Set close_on_action: false to keep Raffi open after running this entry, or true to close even when general.close_on_action is false (or --keep-open is passed).

raise boolean (default: general.raise_running, else false)

When the app already has a window open, Enter focuses it instead of starting the app again, and Ctrl+Enter starts a new one. Works on Hyprland, niri and sway with Raffi’s own window. See raise_running.

window_class string or list of strings (default: the binary’s file name)

The window class (Hyprland, Xwayland apps) or app ID (niri, sway) that raise looks for. Case does not matter, and slack also matches com.slack.Slack. Without it, only a plain binary with no args can raise, by the binary’s file name. Set it for launchers that run a script or pass arguments.

To find the value, look at the class field of hyprctl clients, the app_id in niri msg windows, or the app_id in swaymsg -t get_tree.

alias string

Turns the entry into a shortcut for an internal command. Picking it types the alias into the search box, as if you had entered it yourself, and you carry on from there; nothing runs until you choose a result. Any trigger works: script filters, addons such as audio, web searches, snippets, and so on.

alias cannot be combined with binary, script, args or env; such entries are skipped with a warning. Without a description, the alias text is shown.

keyword string (requires alias)

A short word that stands for the alias while you type. With the entry below, typing linoux torvalds searches exactly like mp linus/linux torvalds (here mp is a script filter keyword), while the search box keeps showing linoux torvalds. Picking the entry from the list types linoux .

Like addon keywords, it is case-sensitive and needs a space after it: linoux alone is a normal search and shows the keyword as a suggestion. A launcher keyword is checked before addon keywords, so it can reuse one. The alias is expanded once and never again, so keywords cannot chain. Keywords cannot contain spaces; if two launchers use the same keyword, the first one keeps it.

launchers.yaml
linoux:
description: "Linus Pull Requests"
icon: github
alias: "mp linus/linux"
keyword: linoux
launchers.yaml
firefox:
binary: firefox
description: "Firefox"
icon: firefox
launchers.yaml
thunar:
binary: thunar
args: ["~/Downloads/"]
description: "Thunar"
launchers.yaml
golang:
binary: goland
description: "Goland"
icon: goland
launchers.yaml
rbw-pass:
binary: rofi-rbw
args:
[
"--selector wofi --clipboarder wl-copy --action copy-password --typer xdotool",
]
description: "Password Manager"
icon: password-manager
ifenvset: WAYLAND_DISPLAY

See Conditions for conditional visibility options.

launchers.yaml
suspend:
binary: systemctl
args: [suspend]
description: "Suspend/Sleep or Hibernate"
icon: system-suspend-hibernate
reboot:
binary: systemctl
args: [reboot]
description: "Reboot / Restart"
icon: gnome-session-reboot
launchers.yaml
google-meet:
binary: google-chrome
args:
[
"--profile-directory=Default",
"--app-id=kjgfgldnnfoeklkmfkjfagphfepbbdan",
]
description: "Google Meet"
icon: "google-meet"
disabled: true

Raffi automatically validates entries on startup. An entry is hidden if:

  1. disabled is set to true
  2. The binary (or interpreter for scripts) doesn’t exist in PATH
  3. Conditional checks fail (see Conditions)

Raffi searches for binaries in directories listed in the PATH environment variable. If a binary path is:

  • Relative (e.g., firefox) - Raffi searches PATH
  • Absolute (e.g., /usr/bin/firefox) - Raffi checks if the file exists
  • Expanded (e.g., ~/bin/myapp) - Raffi expands the path, then checks existence

Entries can be organized in any order in your configuration file. Raffi lists the ones you use first, ranked by sort_mode; the rest keep the order they have in the file.

launchers.yaml
# Browsers
firefox:
binary: firefox
description: "Firefox"
icon: firefox
chrome:
binary: chromium
description: "Chromium"
icon: chromium
# System tools
suspend:
binary: systemctl
args: [suspend]
description: "Suspend/Sleep"
icon: system-suspend-hibernate
reboot:
binary: systemctl
args: [reboot]
description: "Reboot"
icon: gnome-session-reboot

On Hyprland, niri and sway, raise focuses the app’s open window, or starts the app when it has none:

launchers.yaml
slack:
binary: slack
args: ["--enable-features=UseOzonePlatform", "--ozone-platform=wayland"]
description: "Slack"
icon: slack
raise: true
window_class: Slack

Set general.raise_running: true to do the same for every installed app and plain launcher. Elsewhere, a helper such as jumpapp does the job:

launchers.yaml
wally:
binary: jumpapp
args: ["-X", "wally"]
description: "Wally"
icon: wally
ifexist: wally
launchers.yaml
ssh-pi:
binary: kitty-ctrl
args: ["jump", "-t", "PI", "ssh", "pi"]
description: "PI"
icon: raspberry
launchers.yaml
chrome-work:
binary: chromium
args: ["--profile-directory=Work"]
description: "Chromium (Work Profile)"
icon: chromium