Technical Reference
Architecture Overview
Which Browser runs a lightweight HTTP server that listens for OS-level URL intents. The flow looks like this:
- System default browser hook – The OS launches the Which Browser executable with the requested URL.
- Intent capture – The app records metadata (URL, timestamp, originating bundle/app, clipboard selection).
- Rule evaluation – Declarative rules evaluate first; if none match, the scripting engine runs.
- Action dispatch – The resulting action is executed (launch browser profile, queue, snooze, discard, etc.).
- Persistence – Every step writes to the local SQLite database so History can be queried later.
Configuration Files
| File | Purpose |
|---|---|
settings.yaml | Stores high-level preferences such as theme, notification cadence, and queue retention. |
browsers.yaml | List of installed browsers, CLI flags, and per-profile overrides. |
rules.yaml | Export/import format for the human-readable DSL. |
scripts/*.wb | Plain-text scripts that can be version controlled. |
These files are stored under ~/Library/Application Support/WhichBrowser/ (macOS), ~/.config/whichbrowser/ (Linux), and
%AppData%\WhichBrowser\ (Windows).
Scripting Language Cheatsheet
| Helper | Description |
|---|---|
matchUrl(pattern) | Glob matching against the full URL, including scheme and query string. |
matchHost(hostname) | Exact match for the host component. |
matchApp(bundleId) | Matches the originating bundle or executable name. |
between(hours) | Returns true if the local time is within the provided window (for quiet hours). |
useProfile(name) | Resolves to a browser/profile combination defined in browsers.yaml. |
queueUntil(timestamp) | Returns an action that holds the intent until the provided ISO 8601 timestamp. |
labels([...]) | Adds custom labels to the entry for filtering in History. |
Scripts return action(...) objects with the following keys:
openIn– Browser/profile identifier.queue– Boolean or time expression.snoozeUntil– RFC 3339 timestamp.labels– Array of strings.notes– Markdown string stored with the entry.
CLI Utilities
Run whichbrowser --help to see the full list. Common commands:
whichbrowser import rules.yaml– Bulk-import declarative rules.whichbrowser export scripts --out ./scripts– Save all inline scripts to disk.whichbrowser queue --list– Inspect every queued intent from the terminal.whichbrowser run path/to/script.wb --dry-run url– Test a script against a URL without opening a browser.
Automation API
Which Browser exposes a local HTTP API on http://127.0.0.1:15492. Authentication is handled via a random token stored in the
config directory. Example endpoints:
POST /v1/intents– Inject a synthetic intent (JSON payload withurl,source,labels).POST /v1/rules/reload– Force the rules engine to refresh after editing files on disk.GET /v1/queue– Returns pending, snoozed, and history entries.
You can script these endpoints via curl, Python, or your preferred automation framework.
Troubleshooting
| Symptom | Resolution |
|---|---|
| Links still open in Chrome/Safari | Re-run the default browser assignment and ensure “Always use this app” is checked on Windows. |
| Script errors | Open the Scripts tab; runtime errors appear inline with stack traces and suggested fixes. |
| Notifications missing | macOS users should grant Which Browser notification permission in System Settings → Notifications. |
| CLI cannot connect | Confirm the desktop app is running; the automation API only binds when the UI is active. |
For in-depth questions, file an issue with the script you attempted and the log output located in the config directory.