Rule-based,
never asks.
Triage is a native macOS menu-bar app that silently routes every clicked link to the right browser — and the right Chrome profile — based on rules you write in a YAML file.
No picker. No dock icon. No Node runtime. ~500 lines of Swift, single-digit MB of RAM at rest.
$brew install --cask jmanuelrosa/triage/triage Built to disappear.
Six things Triage cares about, and nothing else.
-
Rule-based, never asks
Routes by URL host, path, and source app — first match wins. You write the rules once; Triage just obeys.
-
First-class Chrome profiles
Use friendly names in YAML ("Work [Dev]"); Triage resolves them to Chrome's directory names by reading Local State.
-
Native and invisible
Pure Swift, no Node or Electron. Status-bar item only — no dock icon, no main window. Sleeping process at rest.
-
Live config reload
Edit ~/.config/triage/config.yaml; Triage picks it up on save. Broken YAML pops a modal alert with a plain-text log.
-
Source-app aware
Match by the app the link came from — Slack, WhatsApp, anything. Useful for routing every work-Slack link to the work browser.
-
Silent fallback
URLs that match no rule open in your previous default browser, captured automatically. Configurable via the menu bar.
How it works
One YAML file. Three steps.
Set Triage as your default browser, write a config describing where links should go, and forget it. From then on, every clicked link gets routed deterministically.
- 01
Click a link, anywhere
Slack, Mail, Notes, Terminal — macOS hands the URL to the system default browser via Apple Events.
- 02
Triage matches a rule
The URL host, path, and originating app are evaluated top-down against your YAML. First match wins.
- 03
The right browser opens
Triage shells out: open -na <bundle> --args --profile-directory=<dir> <url>. Then it goes back to sleep.
- →
Match rules use first-match-wins.
host,path, andsource_appare all optional — missing field means match anything.*globs are case-insensitive and anchored.
browsers:
personal:
bundle_id: net.imput.helium
work_general:
bundle_id: com.google.Chrome
profile: "Work"
work_dev:
bundle_id: com.google.Chrome
profile: "Work [Dev]"
rules:
# All work domains go to the dev Chrome profile
- host: "*.example.com"
browser: work_dev
# Specific GitHub orgs go to specific places
- host: github.com
path: "/work-org/*"
browser: work_general
# Anything Slack opens, regardless of URL,
# goes to the work browser
- source_app: Slack
browser: work_general Install
Two paths. Same binary.
macOS 13 or later. Universal binary — Apple Silicon and Intel. The two paths below handle Gatekeeper for you; no Xcode required.
- Recommended
Homebrew
Cask install. Auto-updates with brew upgrade --cask triage. Strips the Gatekeeper quarantine for you.
brew install --cask jmanuelrosa/triage/triage -
Install script
Curl it, inspect it, run it. Downloads the latest release, copies Triage.app to /Applications, registers it with LaunchServices.
curl -fsSL https://raw.githubusercontent.com/jmanuelrosa/triage/main/Scripts/install.sh | bash
Also available: DMG download · build from source
Unsigned beta — DMG users right-click Triage.app → Open the first time.
How it compares
Several good tools. Different niches.
If you want a picker, use Browserosaurus (free) or Velja (free with paid Pro). If you'd rather write rules in JavaScript, Finicky is excellent. If you'll pay for a polished GUI, use Choosy. If you want a tiny native binary you configure in YAML and never see again — that's Triage.
| Tool | Asks? | Native? | Chrome profiles | Cost | Niche |
|---|---|---|---|---|---|
| Triage | No, rules only | Swift | First-class | Free | Silent rule-based routing, YAML-configured |
| Velja | Picker by default | Swift | Limited | Freemium (Pro) | Picker-first; rule routing is a Pro feature |
| Browserosaurus | Picker | Electron | — | Free | Picker-first, cross-platform-ish |
| Finicky | Rules only | Swift + JSCore | Yes | Free | Rule-based, native — rules in JavaScript |
| Choosy | Configurable | Native | Yes | $12 | Rule-based, native, GUI-configured |
FAQ
Frequently asked questions
Quick answers about installing Triage, writing rules, Chrome profile support, and how it compares to other macOS browser routers.
-
What is Triage?
Triage is a free, open-source macOS menu-bar app that routes every clicked link to the right browser — and the right Chrome profile — based on rules you write in a YAML file. It is written in pure Swift (~500 lines), has no dock icon, and never asks you to pick a browser. -
Is Triage free and open source?
Yes. Triage is MIT-licensed and developed in the open at github.com/jmanuelrosa/triage. There is no paid tier, no telemetry by default, and no account is required to use it. -
What macOS versions does Triage support?
Triage runs on macOS 13 (Ventura) or later. It ships as a universal binary, so it runs natively on both Apple Silicon (M1, M2, M3, M4) and Intel Macs. The app is daily-driven on the latest macOS release. -
How does Triage compare to Velja, Finicky, Browserosaurus, and Choosy?
Triage is rule-first and picker-free, like Finicky, but configured in YAML instead of JavaScript. Velja and Choosy lean on a graphical picker; Browserosaurus is an Electron picker. Triage is also fully free and open-source, where Velja and Choosy are paid or freemium. -
Can Triage route links to different Chrome profiles?
Yes — Chrome profile routing is first-class. You reference profiles by their friendly display name in YAML (for example"Work [Dev]") and Triage resolves them to Chrome's internal directory names by reading Chrome'sLocal Statefile. -
Does Triage ever ask which browser to use?
No. Triage is rules-only and never shows a picker. Every URL is evaluated against your YAML config top-down, first-match-wins. URLs that match no rule open in your previous default browser (captured automatically the first time you launch Triage). -
How do I write rules?
Rules live in~/.config/triage/config.yamlas a list of objects with optionalhost,path, andsource_appmatchers plus a targetbrowser. Save the file and Triage live-reloads. Broken YAML triggers a modal alert with a plain-text error log. -
Can Triage match links by the source app, like Slack or WhatsApp?
Yes. Each rule can include asource_appmatcher, so you can send every link clicked from Slack to your work browser, every link clicked from WhatsApp to your personal browser, and so on — independent of the URL itself. -
What happens to a link that doesn't match any rule?
Triage opens it in your previous default browser, which it captures automatically the first time you set Triage as the system default. You can change the fallback at any time from the menu-bar item, without editing the YAML. -
How do I install Triage?
Recommended:brew install --cask jmanuelrosa/triage/triage. Homebrew handles the Gatekeeper quarantine and updates viabrew upgrade --cask triage. You can also use the curl install script, download the DMG from GitHub Releases, or build from source. -
Is Triage code-signed and notarized?
Not yet — Triage is currently an unsigned beta. Homebrew users get the quarantine attribute stripped automatically. DMG users need to right-click Triage.app and choose Open the first time. Code signing and notarization are on the roadmap before the 1.0 release.
More questions? Open an issue on GitHub.