npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@adrianlynch/browserfi

v1.2.0

Published

Per-context browser app bundles for macOS.

Readme

browserfi

Per-context browser app bundles for macOS. Each generated .app gets its own bundle id, display name, icon, and profile directory, so AeroSpace or any window manager that routes by app id can send each browser context to its own workspace.

Why

A single browser app normally shares one bundle id, one profile, and one storage namespace. That makes it hard to:

  • route different browser windows to different AeroSpace workspaces by app id,
  • keep multiple local dev servers from sharing localStorage and cookies,
  • use different signed-in sessions per project.

browserfi duplicates the source browser .app, changes its metadata, installs a small launcher wrapper that pins the profile path, applies a custom icon, and re-signs the result ad-hoc.

Requirements

  • macOS
  • Node.js 20+
  • One or more supported browsers installed in /Applications
  • Built-in macOS tools: codesign, PlistBuddy, sips, iconutil, xattr, and lsregister

Supported browser adapters:

  • chromium
  • chrome
  • chrome-canary
  • brave
  • edge
  • firefox

Safari is intentionally unsupported because it does not expose a clean per-launch profile directory flag.

Install

From npm:

npm install -g @adrianlynch/browserfi

From source:

npm install
npm run build
./dist/cli.js help

Homebrew support should be packaged as a tap formula that installs the npm package or a built release artifact. The intended command is:

brew install adrianlynch/tap/browserfi

Quick Start

  1. Edit .browserfi.toml.
  2. Drop optional per-bundle icons into icons/<key>.png|jpg|jpeg|icns.
  3. Run the interactive UI:
browserfi

Or build everything directly:

browserfi build

Re-running is safe: existing bundles are skipped, icons are still re-applied, and changed bundles are re-signed. Pass --force to rebuild generated .app bundles from scratch while preserving profile data:

browserfi build --force

The interactive UI shows a compact table with installed/missing status and a detail panel for the selected bundle. Run browserfi with no command, or use browserfi tui, to open it. Use arrow keys to select a row, then:

  • enter/e: edit config values inline
  • a: add new app
  • b: build selected app
  • d: delete app
  • w: write AeroSpace rules
  • q: quit

Deleting an app removes its generated .app, profile data, and config row after confirmation.

The browser field is selected from supported browsers that are installed on the machine. In the edit form, use ↑/↓ to move between fields and enter to open browser/workspace selectors. Press s to save. New apps get a filesystem-safe key generated from the display name; existing apps keep their current key when renamed. The icon field accepts a .svg, .png, .jpg, .jpeg, or .icns path or URL; leave it blank to use the icons/<key>.png|jpg|jpeg|icns convention. The icon color pickers set iconColor and iconBackgroundColor, which customize SVG icons during build. If AeroSpace config is found, Browserfi shows workspace fields and lets you choose from existing AeroSpace workspace names. If AeroSpace is not found, workspace fields and AeroSpace actions are hidden.

List configured bundles as a table:

browserfi list

Machine-readable and path-only output are also available:

browserfi list --wide
browserfi list --json
browserfi list --paths

Print AeroSpace rules:

browserfi aerospace

Write those rules into a managed block in your AeroSpace config:

browserfi aerospace --write

Create a starter config:

browserfi init

Config

browserfi uses TOML because it is comfortable to edit by hand: comments are allowed, values are not indentation-sensitive, and repeated [[bundles]] sections read cleanly.

Config lookup order:

  1. ./.browserfi.toml
  2. ./browserfi.toml
  3. $XDG_CONFIG_HOME/browserfi/browserfi.toml, or ~/.config/browserfi/browserfi.toml
  4. ~/.browserfi.toml
installDir = "/Applications"
profilesDir = "~/ChromiumProfiles"
iconsDir = "./icons"

[[bundles]]
browser = "chromium"
key = "user-console-monorepo"
displayName = "User Console Monorepo"
defaultUrl = "https://example.com"
appType = "browser"
workspace = "6_User_Console"

Each bundle supports:

  • browser: one of the supported adapters; defaults to chromium
  • key: stable identifier used for profiles and icons
  • id: optional stable app identity; defaults to key
  • displayName: Finder, Dock, and menu bar name; also used for the .app filename
  • defaultUrl: optional http or https URL opened when the app starts
  • appType: optional Chrome-family launch type when defaultUrl is set: browser keeps the address bar and tabs, app hides them
  • icon: optional .svg, .png, .jpg, .jpeg, or .icns path or URL for this app
  • iconColor: optional SVG tint color, as a 6-digit hex value like #34CDD7
  • iconBackgroundColor: optional SVG background color, as a 6-digit hex value like #111111
  • iconInset: optional SVG/PNG/JPG artwork inset size: none, small, medium, or large; defaults to none
  • workspace: optional AeroSpace workspace for printed rules
  • sourceApp: optional override for the source .app
  • installDir, profilesDir, iconsDir: optional per-bundle path overrides
  • bundleIdPrefix, executableName: advanced overrides

Keys and ids may contain only letters, numbers, dots, underscores, and hyphens. Display names must not be empty or contain /.

defaultUrl works for every supported browser. appType = "app" is only supported for Chrome-family browsers: Chromium, Chrome, Chrome Canary, Brave, and Edge. Firefox always opens the URL in normal browser mode.

Generated apps are written as <displayName>.app. Browserfi marks generated bundles in Info.plist with ownership metadata. If a target app name already exists, Browserfi only overwrites it when it is managed by the same config and same bundle id. Apps from other Browserfi configs, or third-party apps such as Google Chrome, are rejected until the existing app is deleted manually.

Custom Icons

Set icon on a bundle to use a specific SVG, PNG, JPG, or ICNS file. Local paths and http(s) URLs are supported:

[[bundles]]
browser = "chromium"
key = "user-console-monorepo"
displayName = "User Console Monorepo"
icon = "./icons/console.icns"
[[bundles]]
browser = "chromium"
key = "docs"
displayName = "Docs"
icon = "https://example.com/icon.svg"
iconColor = "#34CDD7"
iconBackgroundColor = "#111111"
iconInset = "small"

If icon is not set, Browserfi looks for a square PNG or JPG, ideally 1024x1024, or a pre-built .icns in icons/, named after the bundle key:

icons/<key>.png
icons/<key>.jpg
icons/<key>.jpeg
icons/<key>.icns

browserfi build picks icons up by explicit path, URL, or convention. It downloads URL icons during build, converts SVG, PNG, and JPG files to ICNS, replaces Contents/Resources/app.icns, deletes CFBundleIconName from Info.plist, re-signs ad-hoc, and refreshes Launch Services.

Image icons are normalized onto a 1024x1024 canvas before conversion. Browserfi preserves SVG viewBox values, optionally insets SVG/PNG/JPG artwork so it does not touch the macOS icon edges, optionally tints SVG non-none fills and strokes with iconColor, and optionally paints iconBackgroundColor behind SVG artwork. Set iconInset to none, small, medium, or large; these map to 0px, 96px, 144px, and 192px padding on each side of the 1024x1024 canvas. ICNS icons are used as supplied.

The legacy helper build-icon.sh can still build a simple macOS-style PNG from an SVG:

./build-icon.sh <key> <svg-url-or-path>

AeroSpace

Each generated bundle is detectable by app id:

[[on-window-detected]]
if.app-id = "com.adrian.chromium-<id>"
run = "move-node-to-workspace <workspace>"

browserfi aerospace prints rules for every bundle with a workspace value. browserfi aerospace --write updates a managed block in your AeroSpace config:

# BEGIN browserfi
[[on-window-detected]]
if.app-id = "com.adrian.chromium-user-console-monorepo"
run = "move-node-to-workspace 6_User_Console"
# END browserfi

By default, browserfi writes to whichever AeroSpace config exists:

  1. ~/.aerospace.toml
  2. $XDG_CONFIG_HOME/aerospace/aerospace.toml, or ~/.config/aerospace/aerospace.toml

If both exist, pass --aerospace-config <path> explicitly. Add --reload to run aerospace reload-config after writing.

Project Layout

src/                    TypeScript CLI source
.browserfi.toml         Local bundle config
browserfi.example.toml  Starter config for browserfi init
icons/                  Per-bundle icon files
make-bundles.sh         Legacy Bash implementation
build-icon.sh           Legacy SVG-to-PNG icon helper

Caveats

  • Bundles are re-signed ad-hoc, so first launch may require System Settings -> Privacy & Security -> Open Anyway.
  • Browser auto-updaters usually update the original app only. Re-run browserfi build --force after updating the source browser.
  • Firefox support uses -profile <dir> -no-remote; Chromium-family browsers use --user-data-dir=<dir>.