Skip to content

Publish blit binary via npm (blit-bin)#66

Merged
pcarrier merged 2 commits into
mainfrom
npm-blit-bin
Jun 12, 2026
Merged

Publish blit binary via npm (blit-bin)#66
pcarrier merged 2 commits into
mainfrom
npm-blit-bin

Conversation

@pcarrier

@pcarrier pcarrier commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

What

Publish the blit binary to npm so it can be installed (npm i -g blit-bin) and bundled into downstream tools.

This adds a thin blit-bin launcher plus per-platform blit-bin-<os>-<cpu>[-musl] data packages. The launcher lists the platform packages as optionalDependencies with os/cpu/libc filters, so npm installs exactly one prebuilt binary — the one matching the host — and nothing else.

graph TD
  U["npm i blit-bin"] --> L["blit-bin launcher"]
  L -->|"optionalDependencies: os, cpu, libc"| P{"host"}
  P -->|"linux x64 glibc"| A["blit-bin-linux-x64"]
  P -->|"linux x64 musl"| B["blit-bin-linux-x64-musl"]
  P -->|"linux arm64"| C["blit-bin-linux-arm64 (plus -musl)"]
  P -->|"darwin arm64"| D["blit-bin-darwin-arm64"]
  P -->|"win32 x64"| E["blit-bin-win32-x64"]
  L -.->|"bin launcher execs"| A
Loading

Import API

The default export is the absolute filesystem path to the blit executable (the ffmpeg-static / @esbuild/* convention), so downstreams can spawn it:

import blit from "blit-bin";
import { spawn } from "node:child_process";
spawn(blit, ["open"], { stdio: "inherit" });

Identical in CommonJS (const blit = require("blit-bin")). Resolution happens eagerly at import and throws an actionable error if the matching optional package was omitted. Lower-level helpers (binaryPath, binaryName, candidatePackages, isMusl) are available as named exports and on the blit-bin/resolve subpath. Ships dual ESM (index.mjs) + CJS (index.js) with an exports map and index.d.ts typing the default as string.

Pipeline

  • bin/build-npm-bin-packages repackages the existing release artifacts (blit_<ver>_<os>[-musl]_<arch>.tar.gz + blit_<ver>_windows_x86_64.zip) into the per-platform packages and the launcher, pinning optionalDependencies to the release version.
  • bin/publish-npm-bin-packages publishes platform packages first, launcher last.
  • New publish-bin-npm job in release.yml (needs release) downloads tarballs-* + windows-x86_64 and publishes with --provenance --access public (OIDC — same tokenless setup as the existing @blit-sh/* job).

The platform matrix tracks exactly what CI builds today (linux x64/arm64 glibc+musl, darwin arm64, win32 x64); the generator auto-discovers any artifact, so adding e.g. darwin-x64 later needs no script change.

Verified locally

  • Generator emits all packages + launcher once each with correct os/cpu/libc and version pinning.
  • ESM import blit from and CJS require both return the path and spawn the binary; CLI (bin/blit) works with exit-code/signal passthrough.
  • npm pack --dry-run file lists clean; tsc (nodenext) confirms default is string and the /resolve subpath resolves; release.yml parses and artifact names match the build workflows.

Add a blit-bin npm launcher plus per-platform blit-bin-<os>-<cpu>[-musl]
data packages generated from the existing release tarballs/zip, so the
host installs exactly one prebuilt binary through optionalDependencies.

The default export is the absolute path to the blit executable
(ffmpeg-static convention), so downstreams can:

  import blit from "blit-bin";
  spawn(blit, ["open"], { stdio: "inherit" });

Ships dual ESM/CJS entries, a blit-bin/resolve subpath, and .d.ts types.
A new publish-bin-npm release job builds and publishes these from the
artifacts the release already produces, using OIDC provenance.
@github-actions

Copy link
Copy Markdown

Coverage

Crate Lines Functions Regions
alacritty-driver 63.7% (626/982) 67.1% (49/73) 64.3% (919/1429)
browser 0.0% (0/807) 0.0% (0/65) 0.0% (0/1370)
cli 28.1% (1208/4299) 41.3% (171/414) 31.1% (2182/7019)
compositor 1.0% (93/9234) 2.0% (8/400) 1.2% (146/12408)
fonts 76.8% (486/633) 85.5% (47/55) 77.9% (922/1183)
gateway 25.7% (362/1411) 29.0% (36/124) 19.4% (449/2318)
proxy 18.3% (150/818) 20.9% (24/115) 20.4% (260/1277)
remote 71.5% (1975/2763) 81.4% (188/231) 74.1% (3737/5045)
sd-notify 73.9% (68/92) 100.0% (6/6) 83.2% (109/131)
server 18.7% (2186/11701) 33.6% (251/748) 20.1% (3660/18180)
ssh 1.9% (7/374) 3.2% (1/31) 0.7% (4/613)
webrtc-forwarder 2.7% (72/2624) 2.1% (4/187) 1.2% (50/4335)
webserver 63.5% (753/1185) 70.8% (121/171) 67.8% (1380/2034)
Total 21.6% (7986/36923) 34.6% (906/2620) 24.1% (13818/57342)

@pcarrier pcarrier merged commit dc9dec5 into main Jun 12, 2026
9 of 11 checks passed
@pcarrier pcarrier deleted the npm-blit-bin branch June 12, 2026 01:51
pcarrier added a commit that referenced this pull request Jun 12, 2026
## What

Rename the npm packages that ship the `blit` binary from the unscoped
`blit-bin` / `blit-bin-<platform>` to the **`@blit-sh`** scope, matching
the existing `@blit-sh/*` packages (`browser`, `core`, `react`,
`solid`).

| before | after |
| --- | --- |
| `blit-bin` | `@blit-sh/bin` |
| `blit-bin-linux-x64` | `@blit-sh/bin-linux-x64` |
| `blit-bin-linux-x64-musl` | `@blit-sh/bin-linux-x64-musl` |
| `blit-bin-linux-arm64[-musl]` | `@blit-sh/bin-linux-arm64[-musl]` |
| `blit-bin-darwin-arm64` | `@blit-sh/bin-darwin-arm64` |
| `blit-bin-win32-x64` | `@blit-sh/bin-win32-x64` |

The launcher still installs **exactly one** prebuilt binary for the host
via `optionalDependencies` + `os`/`cpu`/`libc` filters.

## Import API (unchanged shape)

Default export is the absolute path to the platform `blit` executable:

```js
import blit from "@blit-sh/bin";
import { spawn } from "node:child_process";
spawn(blit, ["open"], { stdio: "inherit" });
```

Identical in CommonJS (`require("@blit-sh/bin")`). Helpers remain
available as named exports and on `@blit-sh/bin/resolve`.

## Changes

- `git mv npm/blit-bin -> npm/bin`; rewrote package names across the
resolver, ESM/CJS entries, CLI, `.d.ts`, README, and both
`bin/*-npm-bin-packages` scripts.
- `release.yml` is untouched: the `publish-bin-npm` job already calls
the scripts by path and publishes with `--provenance --access public`
(scoped packages need `--access public`, already passed).

## Verified locally

- Generator emits `@blit-sh/bin` + 6 `@blit-sh/bin-<platform>` packages
into the nested `@blit-sh/` dir layout, with correct `os`/`cpu`/`libc`,
version pinning, and `optionalDependencies`.
- Scoped `node_modules/@blit-sh/*` resolution: ESM default import, CJS
`require`, `@blit-sh/bin/resolve` subpath, spawn, and CLI all work.
- Publisher walks the nested dirs in order (platform packages first,
launcher last).
- `prettier --check .` clean; `npm pack --dry-run` produces
`blit-sh-bin-<ver>.tgz` with the expected 8-file list.

Follow-up to #66 (now merged); branches off latest `main`.
pcarrier added a commit that referenced this pull request Jun 12, 2026
## What

Rename the npm packages that ship the `blit` binary from the unscoped
`blit-bin` / `blit-bin-<platform>` to the **`@blit-sh`** scope, matching
the existing `@blit-sh/*` packages (`browser`, `core`, `react`,
`solid`).

| before | after |
| --- | --- |
| `blit-bin` | `@blit-sh/bin` |
| `blit-bin-linux-x64` | `@blit-sh/bin-linux-x64` |
| `blit-bin-linux-x64-musl` | `@blit-sh/bin-linux-x64-musl` |
| `blit-bin-linux-arm64[-musl]` | `@blit-sh/bin-linux-arm64[-musl]` |
| `blit-bin-darwin-arm64` | `@blit-sh/bin-darwin-arm64` |
| `blit-bin-win32-x64` | `@blit-sh/bin-win32-x64` |

The launcher still installs **exactly one** prebuilt binary for the host
via `optionalDependencies` + `os`/`cpu`/`libc` filters.

## Import API (unchanged shape)

Default export is the absolute path to the platform `blit` executable:

```js
import blit from "@blit-sh/bin";
import { spawn } from "node:child_process";
spawn(blit, ["open"], { stdio: "inherit" });
```

Identical in CommonJS (`require("@blit-sh/bin")`). Helpers remain
available as named exports and on `@blit-sh/bin/resolve`.

## Changes

- `git mv npm/blit-bin -> npm/bin`; rewrote package names across the
resolver, ESM/CJS entries, CLI, `.d.ts`, README, and both
`bin/*-npm-bin-packages` scripts.
- `release.yml` is untouched: the `publish-bin-npm` job already calls
the scripts by path and publishes with `--provenance --access public`
(scoped packages need `--access public`, already passed).

## Verified locally

- Generator emits `@blit-sh/bin` + 6 `@blit-sh/bin-<platform>` packages
into the nested `@blit-sh/` dir layout, with correct `os`/`cpu`/`libc`,
version pinning, and `optionalDependencies`.
- Scoped `node_modules/@blit-sh/*` resolution: ESM default import, CJS
`require`, `@blit-sh/bin/resolve` subpath, spawn, and CLI all work.
- Publisher walks the nested dirs in order (platform packages first,
launcher last).
- `prettier --check .` clean; `npm pack --dry-run` produces
`blit-sh-bin-<ver>.tgz` with the expected 8-file list.

Follow-up to #66 (now merged); branches off latest `main`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant