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

@burdenoff/desktop-shell

v2026.825.3

Published

Shared Electron main-process + preload runtime for Burdenoff product app shells (tray, native menus, window state, notifications, badges, theme sync, auto-update UX, deep links).

Readme

@burdenoff/desktop-shell

The shared Electron runtime and build tooling behind every Burdenoff desktop app shell — tray, native menus, window state, notifications, badges, theme sync, auto-update UX and deep links in one package, plus the burdenoff-desktop CLI that stages, launches, smoke-tests and verifies a shell.

Before this package each of the ~40 app shells carried its own 30 kB electron/main.cjs, its own scripts/prepare-electron.mjs, and its own copy of a "build" block in package.json. They drifted, and the drift shipped.

The two bugs this fixes

1. The packaged app shipped no node_modules. directories.app pointed at electron/build/app, a folder the stage script filled with the web build and two .cjs files — and nothing else. Inside the packaged asar, require('electron-updater') and require('@capgo/electron-updater') therefore threw at startup. Both were wrapped in try/catch, so every released installer looked healthy while auto-update and CapGo OTA were silently dead.

burdenoff-desktop stage now bundles electron/main.cjs with bun build --target=node --format=cjs --external electron, inlining @burdenoff/desktop-shell and electron-updater, and then asserts the output contains no bare updater imports. CapGo is already embedded in the published desktop-shell bundle with a streaming extractor that rejects symlinks, path escapes and oversized archives. A staged app that still needs node_modules fails the build.

2. The sandboxed preload could not require CapGo. Sandboxed preloads resolve only electron and a handful of builtins. Any npm require from the preload is a hard failure, so the renderer bridge never appeared. The preload is bundled the same way and asserted against an explicit allow-list (electron, events, timers, url).

Both assertions run in stage, in this repo's scripts/verify-bundle.ts, and again as an "assert staged bundle" step in the release workflow.

A third, quieter bug: 38 of 40 shells shipped the default Electron icon, because the old stage script copied build/icon.png only if it happened to exist. stage now resolves an icon explicitly and fails when there isn't a square PNG of at least 512px.

Install into a shell

Four wrapper files, one config slice, one package.json delta:

electron/main.cjs             require('@burdenoff/desktop-shell/main').createDesktopApp(require('./desktop.config.cjs'));
electron/preload.cjs          require('@burdenoff/desktop-shell/preload').installPreload(require('./desktop.config.cjs'));
electron/desktop.config.cjs   module.exports = require('../native.config.json').desktop ?? require('../native.config.json');
electron-builder.config.cjs   module.exports = require('@burdenoff/desktop-shell/builder').createElectronBuilderConfig(require('./electron/desktop.config.cjs'));
{
  "main": "electron/main.cjs",
  "dependencies": { "@burdenoff/desktop-shell": "<CalVer>" },
  "devDependencies": {
    "electron": "^43.4.1",
    "electron-builder": "^26.0.12",
    "playwright-core": "^1.50.0"   // drives `burdenoff-desktop smoke`
  }
}

Removed from the shell: the "build" key, electron-updater, @capgo/electron-updater, @capacitor-community/electron, scripts/prepare-electron.mjs, scripts/electron-launch.mjs, scripts/electron-before-build.cjs, src/electronRuntime.ts.

Canonical scripts, templates and every {{TOKEN}} the fleet generator substitutes: templates/README.md.

Verify with bunx burdenoff-desktop doctor — it must exit 0.

CLI reference

burdenoff-desktop <command> [options]
  -h, --help       this help (or `<command> --help`)
  -v, --version    package version

stage

Builds electron/build/app — the folder electron-builder packages. Replaces scripts/prepare-electron.mjs.

| Option | Default | Meaning | |---|---|---| | --root <dir> | cwd | Shell root | | --env <name> | $BURDENOFF_DESKTOP_ENV | local | alpha | prod (staging/production accepted) | | --web-dist <dir> | dist | Web build to copy in | | --deps-mode <mode> | bundle | bundle inlines every dependency; install writes dependencies into the staged package.json and runs bun install --production --ignore-scripts inside it (documented fallback for a genuinely un-bundleable native module) | | --launch | off | Run launch afterwards |

It: reads the config → resolves the icon (fails if missing) → wipes electron/build/app → copies the web build → bundles main.cjs + preload.cjs → asserts self-containment → writes electron/runtime-config.json and a dependency-free package.json → stages icons + entitlements → on macOS rebrands a dev copy of Electron.app (PlistBuddy + ad-hoc codesign) so the dock icon and menu title are the product's.

launch

burdenoff-desktop launch [--root <dir>] [--env <name>] [-- <electron args>]

Spawns the local Electron on the staged app with stdio inherited, forwarding every BURDENOFF_DESKTOP_* variable (legacy <PREFIX>_ELECTRON_* values are normalised to the canonical names first). On macOS it prefers the rebranded electron/build/<ProductName>.app. Replaces scripts/electron-launch.mjs.

No runtime-config argument is passed on the command line: RUNTIME_ARG_PREFIX is the main → preload channel (URI-encoded JSON via additionalArguments, with cfAccess stripped). Main reads the staged runtime-config.json itself, and BURDENOFF_DESKTOP_* overrides it.

smoke

burdenoff-desktop smoke [--root <dir>] [--packaged <dir>] [--timeout <ms>] [--screenshot <path>] [--no-tray] [--allow-missing-driver]

Launches the staged app (or a packaged build, e.g. electron/dist/linux-unpacked) through playwright-core's Electron driver with BURDENOFF_DESKTOP_SMOKE=1 and asserts:

| Check | Assertion | |---|---| | window | a first window opens | | title | equals productName | | bridge | window.__burdenoffDesktop.product.id equals product | | diagnostics | globalThis.__burdenoffDesktopDiagnostics is published | | protocol | protocolRegistered | | menu | menu | | tray | tray (skipped with --no-tray — headless CI has no tray host) | | deep-link | app.emit('open-url', …, '<scheme>://app/smoke') reaches the renderer | | updater / capgo / webRoot | reported, not asserted |

Writes electron/dist/smoke/window.png and prints a table; exits non-zero with a readable report on failure. Run under xvfb-run on Linux. Without playwright-core it exits 1, or 0 with --allow-missing-driver.

icons

burdenoff-desktop icons [--root <dir>] [--check]

Materialises electron/build/icons/ (electron-builder's buildResources): icon.png from iconSourcepublic/icons/icon-512x512.pngpublic/icons/icon-512.pngelectron/icon.pngbuild/icon.png, plus entitlements.mac.plist from this package. --check reports only. electron-builder renders .icns/.ico from the PNG, so no image library is involved.

doctor

burdenoff-desktop doctor [--root <dir>] [--json]

Read-only verification of a shell — config validity (every problem reported, not just the first), thin wrappers, electron-builder.config.cjs, resolvable icons, required/forbidden dependencies, canonical scripts, leftover legacy files, and the removed "build" key. Prints a table; --json emits { root, product, ok, checks: [{ id, status, summary, problems }] } for the fleet verifier. Exit 1 on any failure.

The expected package.json delta is read from this package's templates/package-scripts.json, so the migration template and the verifier can never drift.

Config contract

src/shared/types.ts is authoritative. The desktop slice of a shell's native.config.json:

{
  "desktop": {
    "product": "vibecontrols",              // slug: Linux executableName, staged package name
    "productName": "VibeControls",          // window title, tray, installer, artifact names
    "appId": "com.vibecontrols.www",        // NEVER rewrite — updater identity + Windows AUMID
    "capgoAppId": "com.vibecontrols.desktop", // omit to disable CapGo OTA
    "scheme": "vibecontrols",               // deep links + Linux MimeType
    "domain": "vibecontrols.com",           // app origins + update feeds
    "devServerPort": 5200,
    "envPrefix": "VIBE",                    // legacy VIBE_ELECTRON_* fallback ("VIBE_ELECTRON" also accepted)
    "appOrigins": { "prod": "https://admin.burdenoff.com" }, // optional override
    "category": { "mac": "public.app-category.developer-tools", "linux": "Development" },
    "links": { "docs": "…", "support": "…", "status": "…" },
    "window": { "width": 1440, "height": 900, "minWidth": 960, "minHeight": 600 },
    "closeToTray": { "win32": true, "linux": false },
    "iconSource": "public/icons/icon-512x512.png",
    "maintainer": "Name <email>",
    "legacyGlobal": true
  }
}

electron/desktop.config.cjs is also accepted as the source and takes priority.

Environment

Every variable is BURDENOFF_DESKTOP_<KEY>, with a fallback to the legacy <envPrefix>_ELECTRON_<KEY> so un-migrated shells and workflows keep working:

| Variable | Effect | |---|---| | ENV | local | alpha | prod | | VERSION | CalVer baked into the staged package.json | | START_URL | dev-server origin the window loads | | UPDATE_FEED_URL | overrides the derived electron-updater feed | | GLOBAL_BASE_URL / WORKSPACE_BASE_URL / PUBLIC_STORE_BASE_URL | gateway overrides | | CF_ACCESS_CLIENT_ID / CF_ACCESS_CLIENT_SECRET | alpha only — baked in so electron-updater can reach the Access-gated alpha downloads host | | DEVTOOLS | open devtools on start |

Defaults derived from domain: prod feed https://<domain>/downloads/latest, alpha feed https://alphadownloads.<domain>/downloads/latest, app origins https://app.<domain> / https://alphaapp.<domain>.

CF Access credentials are baked into alpha builds only — possessing an alpha binary means being on the team. They are never written into a prod or local build, and the CLI redacts them in every log line.

electron-builder config

createElectronBuilderConfig(config, overrides?) derives the whole configuration. Same artifacts as the old hand-copied "build" blocks (AppImage + deb x64, universal dmg + zip, NSIS x64, asar, ${productName}-${version}-${arch}.${ext}), with the fleet fixes:

  • directories.buildResources is electron/build/icons, not build/ — several shells generate build/i18n-bundle.json there;
  • Linux .desktop gets MimeType=x-scheme-handler/<scheme>; — without it deep links silently do nothing on Linux;
  • npmRebuild: false replaces the old beforeBuild: () => false hack;
  • macOS: hardened runtime, gatekeeperAssess: false, entitlements, and notarize: false — notarization is an explicit xcrun notarytool CI step so a build never blocks on Apple credentials;
  • no publish key: the release workflow syncs to S3 itself.

appId is passed through verbatim. Shells differ (com.burdenoff.<p> vs com.<p>.www) and rewriting one orphans every installed user's app data and breaks the updater.

Release flow

bun run electron:build:<env>burdenoff-desktop stage → assert staged bundle → electron-builder --config electron-builder.config.cjs → sign → smoke → S3 → CloudFront invalidation.

templates/workflows/release-electron.yml is the canonical pipeline (workflow_dispatch with platforms/channel/version/dry_run/mark_latest): a capgo-ota job (production only), linux / macos (macos-15) / windows build jobs, and a publish job uploading downloads/<ver>/<os>/, mirroring downloads/latest/<os>/ with stable un-versioned aliases, writing manifest.json and invalidating CloudFront. macOS signs with CSC_LINK and notarizes/staples via notarytool; Windows signs with azure/[email protected] and then re-computes the latest.yml sha512/size, because signing rewrites the binary after electron-builder hashed it and electron-updater would otherwise reject the download.

templates/workflows/native-smoke.yml is the ~6-minute path-filtered PR guard: install → doctor → build → stage → electron-builder --dir --linuxxvfb-run burdenoff-desktop smoke --packaged → screenshot artifact.

Migration checklist

  1. Add the desktop slice to native.config.json.
  2. Stamp electron/main.cjs, electron/preload.cjs, electron/desktop.config.cjs, electron-builder.config.cjs.
  3. Apply templates/package-scripts.json (merge scripts/deps, apply remove).
  4. Delete scripts/prepare-electron.mjs, scripts/electron-launch.mjs, scripts/electron-before-build.cjs, src/electronRuntime.ts, and the "build" key.
  5. Ensure a square PNG ≥512px exists (public/icons/icon-512x512.png).
  6. Stamp both workflows.
  7. bun install && bunx burdenoff-desktop doctor → must exit 0.
  8. bun run electron:run:local — window, tray, menu, deep link.
  9. bunx burdenoff-desktop smoke (add --no-tray on headless Linux).
  10. Release dry run: Release Electron with dry_run=true.

Developing this package

bun install
bun run sanity        # lint + format + type:check + test + build
bun run build         # dist/{main,preload,builder,config,cli}.cjs + d.ts
bun run scripts/verify-bundle.ts

test/fixture-shell/ is a minimal shell used by .github/workflows/smoke.yml to exercise doctor, icons, stage and smoke end to end without depending on a product repo.

License: proprietary — Burdenoff Consultancy Services Pvt. Ltd.