Moving from Finicky
Grinch is inspired by Finicky and supports many Finicky v4 configs. Copy yours across, validate it, and adjust the few places listed below.
Move your config
- Install Grinch and add the
Grinchalias. - Copy your Finicky config to a location Grinch reads. If yours lives
somewhere other than
~/.finicky.js, copy that file instead:Terminal mkdir -p ~/.config cp ~/.finicky.js ~/.config/grinch.js - Run
Grinch --validate. If it reports an error, check what to change. - Quit Finicky, open Grinch, and choose Grinch under System Settings → Desktop & Dock → Default web browser.
- Check a few links with
Grinch --test <url>. Bare-string matchers behave differently; see the first item under what to change.
If you use Finicky's Chrome or Firefox add-on, point it at
grinch://open/….
What works as-is
export default { … }as well asmodule.exports.- Finicky's key names:
defaultBrowser,handlers, and a rule'sbrowserare aliases fordefault,rules, andopen. - Wildcard and regex matchers, arrays of matchers,
nullto open nothing, and combined{match, url, browser}entries. - Rewrite functions, including the legacy URL-object return shape, and
undefinedas "leave unchanged". ctx.openerwith the same meaning as Finicky v4'soptions.opener.appType:"appName","bundleId","path", and"none". When you leave it out, Grinch recognizes app paths first, then looks up the value as an installed bundle ID or app name. If neither lookup succeeds, it uses the value as a bundle ID.- Option keys such as
hideIconandlogRequests.urlShortenersandkeepRunningare accepted but have no effect.
What to change
Bare-string matchers match hostnames
In Grinch, match: "github.com" matches the host and its
subdomains. In Finicky v4, the same string is compared with
=== against the full URL, so it rarely fires. If your config
relied on exact hostnames, use finicky.matchHostnames("github.com").
See bare-string matchers.
No import or named exports
Grinch turns export default <expr> into
module.exports = <expr> when it loads the config, so
pasting a v4 config works. import lines and named exports such
as export const or export function fail with a
load error that points at module.exports: JavaScriptCore runs
the file as a script, so an import has nothing to resolve against. Inline
what you need, or pre-process the file.
No await fetch()
Grinch decides synchronously, so Finicky's shortenerExpander
pattern can't run. Expand shortened links outside Grinch instead; see
URL shorteners.
Three finicky methods are missing
finicky.notify, finicky.getPowerInfo, and
finicky.getBattery don't exist. Calling one throws a
TypeError. At the top level of the config, the load fails;
inside a matcher or open function, the rule is skipped and a
runtime_js_error event is logged.
windowTitle needs Accessibility permission
Grinch asks for Accessibility permission when it launches. Until you grant
it, opener.windowTitle is "" and rules that depend
on it don't match.
The finicky namespace
Five Finicky v4 methods are present, plus one Grinch helper:
Finicky v3 configs
Port v3 configs with Finicky's migration guide first. Grinch handles the most common v3 leftovers:
url.urlString,url.url, andurl.openerstill return usable values and log a one-line warning naming the v4 equivalent.urlStringreturnsurl.href,url.urlreturns the legacy{protocol, hostname, …}object, andurl.openerreturns the same opener object asctx.opener, ornull. URL-only callbacks do not request opener details; declare(url, ctx)and usectx.opener.url.keysthrows, with a message pointing atctx.modifiersandfinicky.getModifierKeys(). Its v3 shape differs from v4's, and returning the wrong shape silently would send links to the wrong place.
Memory
Finicky bundles a WebKit instance for its config window. In a historical measurement, Grinch used about 15.5 MB of resident memory and Finicky about 142.5 MB. The footprint table has the full comparison.