WrangURL is a macOS menu bar app that opens each link in the right browser. You write rules that match URLs, and WrangURL sends matching links to the browser you choose. If a rule lists more than one browser, a picker lets you choose each time.
If you use WrangURL, please consider sponsoring. It really does help.
Important
I am not a Swift developer, but I've always wanted to try. I found a few open source solutions to link wrangling, but figured this would be a good way to learn. I have not written every line and Claude has made the process easier. But I use this tool daily, so I'm comitted to maintaining it either way. The more I learn the less relient I'll become on AI.
HOW I USE AI CURRENTLY: I'll generally ask Claude to plan changes, and then get it to guide me through the work, explaining as it goes.
WrangURL is built using Claude. Details can be found in PLAN.md and CLAUDE.md
- Match URLs with simple patterns like
localhost,*.example.comorgithub.com/myorg/*, or with regular expressions. - Limit a rule to links clicked in particular apps, such as sending links from Slack to Chrome.
- Send a match straight to one browser, or choose from a picker when a rule lists several.
- Choose what happens to links no rule matches: open them in a fallback browser, or show the picker.
- Hold ⌥⌘ while clicking any link to choose a browser, whatever the rules say.
- Keeps a searchable history of the links it has opened, grouped by day.
- Runs in the menu bar and can open at login.
Requires macOS 14 or later.
On first launch, a short setup assistant asks you to:
- Choose a fallback browser for links that no rule matches.
- Choose whether unmatched links open in the fallback browser or show the picker.
- Set WrangURL as your default browser. WrangURL can only route links from other apps while it's the default. macOS asks you to confirm.
- Optionally open WrangURL at login.
You can run the setup again from Settings → General → Run Setup Again….
Open Edit Rules… from the menu bar icon. Each rule has a pattern and one or more browsers. Rules are checked from top to bottom and the first match wins, so drag rules to reorder them.
Simple patterns match the host and, optionally, the scheme, port and path:
| Pattern | Matches |
|---|---|
localhost |
localhost over http or https, on any port |
http://localhost |
localhost over http only |
localhost:3000 |
localhost on port 3000 only |
*.example.com |
example.com and all of its subdomains |
github.com/myorg/* |
URLs on github.com whose path starts with /myorg/ |
Simple patterns ignore case. A path matches as a prefix, and * is a wildcard.
Regular expressions can match anywhere in the full URL. They're case-sensitive; start the pattern with (?i) to ignore case.
Clicked In limits a rule to links clicked in particular apps. Add apps from the list of running apps, or choose one from disk. With apps listed, the pattern is optional: leave it empty to send every link from those apps to the rule's browsers. A rule limited to apps never matches a link whose source app is unknown, such as one opened with open in Terminal.
To check your rules, use Test a URL at the bottom of the Rules tab. It shows which rule matches and which browser would open. When a rule is limited to apps, choose the app the link is clicked in next to the field. The rule editor has its own test field for the rule you're editing.
The picker appears next to the mouse pointer. The app you clicked the link in stays in front.
To choose a browser for a link that a rule would open directly, hold ⌥⌘ (Option-Command) while you click it. The picker then lists every browser, with the rule's browsers (or the fallback browser) first. To use other keys, click the Always ask when holding field in Settings → General, press the modifier keys you want, and let go. The ⓧ button next to it turns this off. Some apps give modifier-clicks their own meaning, so this only works where the app still hands the link to your default browser.
| Key | Action |
|---|---|
1–9 |
Open in that browser |
← → or Tab |
Move the selection |
Return |
Open in the selected browser |
⌘C |
Copy the link and close the picker |
Esc or click elsewhere |
Cancel |
Choose History… in the menu to see every link WrangURL has opened, grouped by day, with the time, the app the link was clicked in, the rule that matched and the browser it went to. Search filters by URL, browser, rule or source app. The buttons at the end of each row copy the link or open it again through your rules; double-clicking also opens it again. Right-click to copy, open or delete selected links. The trash button in the toolbar clears everything.
WrangURL reads the source app from the request macOS sends when a link is clicked. Links opened with open in Terminal, or sent by an app that has already quit, show no source app.
History is kept only on this Mac, in history.json next to the configuration file, and holds the most recent 5,000 links. Turn it off in Settings → General.
- Settings → General covers the fallback browser, what to do with unmatched links, the keys that always show the picker, launch at login, updates, whether URLs appear in the system log, whether to keep a history, and the default browser status.
- WrangURL checks GitHub for new releases with Sparkle. Choose Check for Updates… in the menu to check now.
- If WrangURL stops being the default browser, the menu bar icon changes to ⚠︎.
- Import… and Export… save and load your rules and settings as JSON.
- Your configuration is stored in
~/Library/Containers/com.thepublicgood.wrangurl/Data/Library/Application Support/WrangURL/config.json. After editing the file by hand, click Reload in Settings → General.
You'll need:
- Xcode 26 or later
- XcodeGen, which generates the Xcode project from
project.yml:brew install xcodegen
xcodegen generate
open WrangURL.xcodeprojThe generated WrangURL.xcodeproj isn't checked in. Run xcodegen generate again after adding or removing files, or after changing project.yml.
To build from the command line:
xcodebuild -project WrangURL.xcodeproj -scheme WrangURL -configuration Release -derivedDataPath build/DerivedData -skipPackagePluginValidation buildSwiftLint runs as part of the build, with its rules in .swiftlint.yml. -skipPackagePluginValidation lets its build plugin run from the command line; in Xcode, click Trust & Enable the first time you build.
The app is written to build/DerivedData/Build/Products/Release/WrangURL.app. Debug and local builds are ad-hoc signed, so they run on your own Mac without a certificate.
When you set a development build as your default browser, macOS records the path of that particular copy. After moving or deleting it, set the default browser again.
Publishing a GitHub release runs .github/workflows/release.yml. It builds the app, re-signs it with a self-signed certificate (scripts/resign.sh) so every release has the same code signing identity, and attaches it to the release as a zip, along with the Sparkle appcast.xml that installed copies check for updates. The release notes become the update notes. The workflow needs the SPARKLE_PRIVATE_KEY repository secret. That's the EdDSA private key whose public half is SUPublicEDKey in project.yml. Export it with Sparkle's generate_keys --account wrangurl -x <file>. It also needs SIGNING_CERTIFICATE_P12 (the base64-encoded "WrangURL Self-Signed" identity, exported from Keychain Access as a .p12) and SIGNING_CERTIFICATE_PASSWORD. The build number is the workflow run number, so each release is newer than the one before it.
scripts/release.sh builds a signed, notarized app and DMG in build/release/. It needs:
-
A Developer ID Application certificate in your keychain.
-
Notarization credentials saved once with:
xcrun notarytool store-credentials WrangURL --apple-id <your Apple ID> --team-id <your team ID>
Set SKIP_NOTARIZE=1 to build and sign without notarizing. There are more details at the top of the script.
Run the tests from Xcode with ⌘U, or from the command line:
xcodebuild -project WrangURL.xcodeproj -scheme WrangURL -derivedDataPath build/DerivedData -skipPackagePluginValidation testThe tests use Swift Testing. They cover:
- pattern matching
- routing decisions
- saving, loading and importing the configuration
- keyboard handling in the picker
While hosting the tests, the app skips its startup actions, so it doesn't open windows or change your configuration.
WrangURL is released under the MIT License. See LICENSE.md.
Copyright © 2026 Warrick Bayman.
