Skip to content

fix(node): stop shipping platform binaries in the main npm package - #413

Merged
kingchenc merged 1 commit into
mainfrom
fix/npm-package-contents
Aug 28, 2026
Merged

fix(node): stop shipping platform binaries in the main npm package#413
kingchenc merged 1 commit into
mainfrom
fix/npm-package-contents

Conversation

@kingchenc

Copy link
Copy Markdown
Collaborator

The published wickra package weighs 98.64 MB unpacked across 22 files. The six platform packages it delegates to occupy 49.18 MB on npm in total — exactly half. Every binary ships twice.

Cause

files listed both npm and *.node. napi artifacts fills npm/<rid>/ with the freshly built binary for each of the six targets before publish, and a copy of each also sits in the package root, so both entries pull in the full set:

 6 x wickra.<rid>.node            (package root, via *.node)
 6 x npm/<rid>/wickra.<rid>.node  (scaffolding dir, via npm)
 6 x npm/<rid>/package.json
 4 x index.js, index.d.ts, package.json, README.md
──
22

Why it is dead weight

index.js resolves ./wickra.<rid>.node first and only falls back to the wickra-<rid> optional dependency. The bundled copy always wins, so the platform package npm downloads alongside it is never loaded. npm install wickra transfers the entire matrix plus one unused platform package.

For scale, comparable napi-rs projects using the same platform-package mechanism:

Package Unpacked
@node-rs/argon2 0.04 MB
@napi-rs/canvas 0.12 MB
@swc/core 0.13 MB
lightningcss 0.49 MB
wickra 98.64 MB

Fix

Dropping only npm would have halved the package rather than fixed it, so both entries go. What remains is index.js, index.d.ts, package.json and the README npm always includes.

npm pack --dry-run   11.1 MB / 11 files  ->  257.2 kB / 4 files

The local root holds one binary; CI holds six, so the published delta is the full 98.64 MB -> ~257 kB.

Verification

  • files governs packing only — the platform packages carry their own files: ["wickra.<rid>.node"] and are published and packed from npm/<rid>/ on disk, which release.yml reaches directly. Nothing in the release path reads the main package's file list.
  • index.js contains no reference to ./npm/; its only mention of the directory name is a URL inside an error message.
  • The 1633 Node tests pass unchanged — local resolution is not affected by files.

Takes effect with the next release; wickra@1.0.2 on npm stays as it is.

The published `wickra` package weighs 98.64 MB unpacked across 22 files. The six platform packages it delegates to occupy 49.18 MB on npm in total — exactly half. Every binary ships twice.

`files` listed both `npm` and `*.node`. `napi artifacts` fills `npm/<rid>/` with the freshly built binary for each of the six targets before publish, and a copy of each also sits in the package root, so both entries pull in the full set:

```
 6 x wickra.<rid>.node            (package root, via *.node)
 6 x npm/<rid>/wickra.<rid>.node  (scaffolding dir, via npm)
 6 x npm/<rid>/package.json
 4 x index.js, index.d.ts, package.json, README.md
```

Consumers never load them. `index.js` resolves `./wickra.<rid>.node` first and only falls back to the `wickra-<rid>` optional dependency, so the bundled copy always wins and the platform package npm downloads alongside it is dead weight. `npm install wickra` therefore transfers the whole matrix plus one unused platform package. Comparable napi-rs projects ship 0.04-0.49 MB: @node-rs/argon2 0.04, @napi-rs/canvas 0.12, @swc/core 0.13, lightningcss 0.49.

Dropping only `npm` would have halved the package rather than fixed it, so both entries go. What remains is index.js, index.d.ts, package.json and the README npm always includes: 11.1 MB -> 257 kB and 11 -> 4 files in a local `npm pack --dry-run` (the local root holds one binary, CI holds six).

`files` governs packing only. The platform packages carry their own `files: ["wickra.<rid>.node"]` and are both published and packed from `npm/<rid>/` on disk, which release.yml reaches directly — nothing in the release path reads the main package's file list. `index.js` contains no reference to `./npm/`; its only mention of the directory name is a URL in an error message. The 1633 Node tests pass unchanged, since local resolution is unaffected by `files`.
@kingchenc
kingchenc merged commit 3edfc2e into main Aug 28, 2026
55 checks passed
@kingchenc
kingchenc deleted the fix/npm-package-contents branch August 28, 2026 19:12
kingchenc added a commit that referenced this pull request Aug 28, 2026
Cuts 1.0.3 for the npm packaging fix in #413.

`wickra@1.0.2` shipped every platform binary twice — 98.64 MB unpacked across 22 files, exactly twice the 49.18 MB the six platform packages occupy on npm together. The published package drops to the four files a consumer actually needs.

## Bump

Run with `bump_version.py`, which reported **seven WARNs**. All seven are false negatives of its name scoper: it requires the package name on the same line as the version, so it cannot see a Maven dependency block or the napi loader. Each was checked and patched by hand.

| File | Occurrences | What |
|---|---|---|
| `SECURITY.md` | 3 | supported-versions prose + table |
| `bindings/java/benchmarks/pom.xml` | 1 | `org.wickra:wickra` dependency |
| `examples/java/pom.xml` | 1 | `org.wickra:wickra` dependency |
| `bindings/node/index.js` | 52 | napi version-check literal |

`git grep 1.0.2` outside `CHANGELOG.md` and the lockfiles is empty afterwards.

## Checked against the #412 regression

The 1.0.1 -> 1.0.2 bump corrupted third-party versions in the npm lockfiles and took down every Node job. Verified that it did not recur:

- both `package-lock.json` files changed only `wickra-*` entries; every third-party version is untouched
- `npm ci` succeeds in `bindings/node` and in `examples/node`
- `Cargo.lock` moved nine entries, all workspace crates

## Local verification

`cargo fmt --all`, `cargo test --workspace --all-features` and `cargo clippy --workspace --all-targets --all-features -- -D warnings` all pass.

The docs and webpage version strings are deliberately untouched — `sync-about.yml` rewrites those on the `v*` tag.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant