package.json has ~55 root scripts. You need four. Everything else belongs to
CI or the release process. This file is a guide, not an inventory — for the full
list, read package.json.
bun install --frozen-lockfile # once
bun scripts/install-wasm-pack.ts # once — pinned, checksum-verified wasm-pack
bun test path/to/focused.test.ts # while editing
bun run verify:ci # before you pushThat is the whole path. verify:ci is the broadest gate you can run locally, and
passing it means a pull request will usually be green.
Two kinds of change need one more command:
| If you changed | Also run |
|---|---|
| Anything rendered in a browser | bun run test:browser (first time: bun run browser:install) |
Rust under packages/wasm |
cargo test, from packages/wasm |
It is composed as VERIFY_CI_NODES in scripts/workspace-tooling.ts and runs, in
order:
- Tooling contract tests, JavaScript dependency audit,
cargo test,cargo audit - Package builds
- Clean-export check, typechecks, lint, unit tests, example builds, Node ESM resolution
- Packed-consumer and bundler-consumer installs
- Public API check and benchmark smoke
- Delivery-size report
It is not a complete mirror of CI. The pipeline additionally runs the full
browser matrix, coverage thresholds, and the production docs build. Matched
timing comparisons run deliberately through the local protocol in
bench/README.md, not as a required CI job. A green verify:ci is strong
evidence, not a guarantee.
When it fails, it prints ::workspace-node::<id> before each step. Node ids are
not always script names — audit:javascript is bun scripts/dependency-audit.ts,
test:rust is cargo test in packages/wasm. To map an id to the exact command:
bun scripts/workspace-tooling.ts verify-ci --dry-runThat lists every node with its command, so you can re-run only the step that failed instead of the whole gate.
Scripts are grouped by prefix. Knowing the prefix is usually enough to find what you want without reading all of them:
| Prefix | What lives there |
|---|---|
build: |
Compiling packages, examples, the WASM engine, the docs site |
test: |
Test suites — unit, browser, coverage, tooling contracts |
typecheck: |
TypeScript, whole workspace or narrowed to one part |
verify: |
Composite gates that prove a real consumer scenario works |
api: |
Public API surface: report it, gate it, re-baseline it |
size: |
Delivery-size measurement and history |
docs: |
Generating and checking the documentation site |
compatibility: |
The Excel/Sheets conformance lab |
release:, changeset: |
Release machinery — maintainers only |
Add a new script under the prefix that owns it. A script nobody can categorise is a script nobody will run.
docs:generateownsdocs/src/generated/*and the API pages. Never hand-edit its output.- Benchmarks live in the
benchworkspace, not here:bun run --filter '@sheetwrite/bench' bench:verify. Baselines underbench/results/and the delivery-size budgets are reviewed evidence — changing one to make a regression pass defeats the gate's only purpose. compatibility:capture:*andcompatibility:roundtrip:libreofficeneed external applications or credentials. They are run deliberately, when refreshing the oracle corpus, not as part of a normal change.release:*assumes a clean tree and specific artifact layouts. Running it casually produces confusing local state. Contributors only ever needbunx changesetto add a changelog entry.