Skip to content

Adding apps & tools

Sooner or later you’ll want Slack, or Discord, or ripgrep, or that one obscure CLI you saw on a blog. Good news: you almost never touch the rice to do it.

The quickest route is Install App in pounce: pick a missing app from the rice’s curated Popular apps shelf or search a package source, choose whether the app belongs in your launcher roster or should only be installed, and pounce writes a small Nix module plus rebuilds. It is declarative, not a hidden imperative install.

Prefer to write it yourself? Edit your host config and rebuild:

Terminal window
haus edit # opens ~/.config/nix/hosts/<hostname>/default.nix
# …add your app or tool…
haus rebuild # build, then switch

Everything you declare there merges with what the rice and pounce-generated package modules already declare. The only question is which option to use.

Or let Pounce make the edit: open Install App and choose Popular apps or where to search (Homebrew, the Mac App Store, or the flake’s pinned Nixpkgs). The curated shelf hides apps already present on the Mac and does not expose which package source backs each pick. Each choice is written as a small Nix module under hosts/<hostname>/packages/ and applied with haus rebuild; a Homebrew cask or App Store app can also be added to the tiling roster, including its launcher key and optional workspace. For a workspace app, Pounce checks the pinned SketchyBar App Font mapping and writes the verified barIcon ligature too. If upstream has no match, the pill keeps its workspace letter rather than guessing an icon.

There’s nothing to set up first — no data files, no options to point at. Each selection lands as its own Nix module under hosts/<hostname>/packages/, and Pounce stages and commits just that file after a successful rebuild.

A GUI app I'll live in

Want it tiled, with a Caps-Lock letter and its own workspace? Add it to the app roster — one entry gives you the key, the workspace, the bar pill, and (optionally) installs it.

A GUI app, no fuss

Just want it installed — no launcher key, no tiling opinions? One line in homebrew.casks.

A CLI tool I'll keep

A command you want on your PATH for good? Add it to home.packages from nixpkgs — and it rolls back with everything else.

A CLI tool, just once

Trying something out? Run it without installing via , (comma). Nothing to clean up.


A GUI app with a launcher key (the roster)

Section titled “A GUI app with a launcher key (the roster)”

This is the nebelhaus-native way to add an app you actually work in. One keyed entry in nebelhaus.apps wires up everything at once: a Caps-Lock letter to launch/focus it, a workspace it lives on, a pill in the bar, the auto-tiling rule, a row in the cheatsheet — and it installs the app for you.

nebelhaus.apps.slack = {
key = "s";
name = "Slack";
workspace = "S";
appId = "com.tinyspeck.slackmacgap";
barIcon = ":slack:";
label = "Slack";
cask = "slack";
};

Rebuild, and tapping then S launches Slack onto workspace S, every time.

The two fields people always have to look up:

  • appId — the app’s bundle id, used to auto-send its windows to the right workspace. Find it once the app exists on disk:

    Terminal window
    osascript -e 'id of app "Slack"'
    # → com.tinyspeck.slackmacgap
  • barIcon — a ligature from the SketchyBar app font (e.g. :slack:, :discord:, :figma:). Browse the list on that page; leave it null and the bar just shows the workspace letter.

The full field-by-field breakdown — and the one-app-per-workspace thinking behind it — lives in Window management and Making it yours.

Some apps you just want installed — a background utility, something you open from Spotlight-muscle-memory, a thing you touch once a month. Skip the roster and drop the Homebrew cask straight in:

homebrew.casks = [
"discord"
"obsidian"
"figma"
];

Your list is merged with the casks the rice already installs (Ghostty, AeroSpace, and any roster apps), so you never repeat or clobber them. Don’t know the cask name? Search it:

Terminal window
brew search --cask obsidian

Some apps only live in the Mac App Store. The smooth path is Pounce → Install App → Mac App Store: type a search, choose the Mac-compatible result, then install it alone or give it a roster key and workspace. Pounce already knows the result’s numeric App Store id and bundle id.

This path uses mas get in a visible floating terminal. You need to be signed into the App Store, and a download may ask for Touch ID or your Apple Account. Paid apps must already have been purchased; if the CLI cannot acquire one, Pounce opens the App Store page for you.

Unlike Homebrew and Nix choices, App Store acquisition itself isn’t captured in a Nix module: it is an Apple Account operation, not part of the Nix generation. A roster entry is still declarative after the app is acquired.

For anything already on the machine — Safari, Music, an app you installed by hand — you don’t need to install it again. If you want it in the launcher, just add a roster entry with cask = null:

nebelhaus.apps.music = {
key = "m";
name = "Music";
workspace = "M";
appId = "com.apple.Music";
barIcon = ":apple_music:";
cask = null;
};

Command-line tools normally come from nixpkgs, which makes them declarative, reproducible, and roll-backable. Pounce → Install App → Nix packages searches the exact Nixpkgs revision pinned by your flake and writes a module under hosts/<hostname>/packages/ that adds the chosen attribute to environment.systemPackages. If you prefer to keep the list in Nix source, personal tools go in your host file’s home-manager block:

home-manager.users.${username} = {
home.packages = with pkgs; [
ripgrep
httpie
ffmpeg
];
};

Not sure of the exact package name? Search nixpkgs:

Terminal window
nix search nixpkgs ripgrep
# …or browse https://search.nixos.org/packages

hearth wires up nix-index and comma, so you can run any command in nixpkgs without installing it — great for one-offs and “does this even do what I think”:

Terminal window
, cowsay "hello fog" # fetches cowsay, runs it, keeps nothing
, ncdu # try a disk-usage TUI once

If you find yourself reaching for it twice, then add it to home.packages.

Some CLIs want an API key. Keep the secret out of your Nix config (it’d land in the world-readable Nix store) — read it from a file at shell startup instead:

home-manager.users.${username} = {
programs.zsh.initContent = lib.mkAfter ''
export OPENAI_API_KEY="$(cat ~/.secrets/openai 2>/dev/null)"
'';
};

The ~/.secrets/* files stay on the machine, ungit-tracked. See Making it yours for the pattern.


  1. haus rebuild — builds first, so a typo can’t take down your running system.

  2. New casks install, new CLI tools land on your PATH, and any new roster app gets its letter, workspace, and bar pill — all in one go.

  3. If a new roster app doesn’t tile on first launch, it’s a one-time hiccup; tap , then Backtick to re-sort everything to its workspace.