Skip to content

chore: provision node and bun via nix instead of pnpm - #1270

Closed
ryoppippi wants to merge 4 commits into
ci/push-main-onlyfrom
chore/provision-node-bun-via-nix
Closed

chore: provision node and bun via nix instead of pnpm#1270
ryoppippi wants to merge 4 commits into
ci/push-main-onlyfrom
chore/provision-node-bun-via-nix

Conversation

@ryoppippi

@ryoppippi ryoppippi commented Jun 11, 2026

Copy link
Copy Markdown
Member

Summary

package.json declared engines.runtime for node and bun with
onFail: download, so pnpm fetched and managed those runtimes itself rather
than using the pinned Nix toolchain. This removes that and provisions both
runtimes explicitly via Nix.

What changed

  • package.json: drop engines.runtime.
  • flake.nix dev shell: add nodejs_24 (bun already present).
  • CI test: install nodejs_24 for Vitest (drop the unused bun).
  • CI pkg-pr-new: add nodejs_24 + bun for the tsdown / ensure-native-binary prepack scripts.
  • CI perf jobs: add nodejs_24 alongside bun.
  • release.yaml: add bun; node still comes from setup-node (kept — needed for npm registry auth / provenance).

Verification

With a clean pnpm state (PNPM_HOME/XDG dirs in a tempdir), after removing
engines.runtime:

  • pnpm install --frozen-lockfile no longer manages/downloads node or bun.
  • pnpm exec vitest run runs on the PATH Nix node (v24.14.1); 34 tests pass.

Notes


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Provision Node and Bun via Nix (using default nodejs/pnpm) so dev and CI run on consistent, pinned runtimes without downloads. Also speeds up tests by installing only the JS tools instead of realizing the full dev shell.

  • Refactors
    • Removed engines.runtime from package.json; regenerated pnpm-lock.yaml to drop runtime: Node/Bun entries.
    • Dev shell: include nodejs and pnpm (replaces nodejs_24/pnpm_11); bun unchanged.
    • CI: use nix profile installs. Tests install pnpm/nodejs/just and run just test-vitest (no nix develop). pkg-pr-new and perf install nodejs + bun. Release installs bun via Nix; keep setup-node for npm auth/provenance.

Written for commit 509f5df. Summary will update on new commits.

Review in cubic

The test job spent ~73s on "Warm Nix dev shell" realizing the complete
development shell — every linter, formatter, renovate, and the pre-commit hook
closure — even though pnpm install itself was only ~7s. Now that coverage is a
`nix build` derivation, Vitest is the sole step that needs a JS toolchain.

Replace `nix develop` with `nix profile install pnpm_11 bun just`, mirroring the
perf-comment and pkg-pr-new jobs, then run `just test-vitest` directly. This
skips the heavy shell closure while keeping the exact tools Vitest needs.
`package.json` declared `engines.runtime` for node and bun with
`onFail: download`, so pnpm fetched and managed those runtimes itself. That
made every environment depend on a pnpm-managed download at runtime instead of
the pinned Nix toolchain.

Drop `engines.runtime` and provide both runtimes explicitly:

- dev shell: add `nodejs_24` (bun was already present).
- test job: install `nodejs_24` for Vitest (dropping the unused bun).
- pkg-pr-new: add `nodejs_24` and `bun` for the tsdown / ensure-native-binary
  prepack scripts that previously relied on the managed runtimes.
- perf jobs: add `nodejs_24` alongside the existing bun.
- release: add `bun`; node still comes from `setup-node`, which is kept for the
  npm registry auth and provenance setup.

Verified locally with a clean pnpm state: `pnpm install --frozen-lockfile` no
longer manages runtimes and Vitest runs on the PATH node.
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ebc7b51d-9ce1-4763-a445-c9cedaa5e3c6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/provision-node-bun-via-nix

Comment @coderabbitai help to get the list of available commands and usage tips.

The lockfile recorded the `engines.runtime` node/bun entries as `runtime:`
dependencies. With `engines.runtime` removed, regenerate the lockfile so
`pnpm install --frozen-lockfile` stays in sync and no longer resolves the
pnpm-managed runtimes.
Base automatically changed from ci/test-job-lean-shell to ci/push-main-only June 11, 2026 15:14

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — mechanical swap from pnpm-managed runtime downloads to Nix-provisioned runtimes for Node.js and Bun across dev shell, CI jobs, and release workflow.

  • Drop engines.runtime from package.json — pnpm no longer manages node/bun downloads at install time
  • Add nodejs_24 to Nix dev shell — bun was already present; node now joins it
  • CI test job — stop realizing full dev shell — replaces nix develop --command true + nix develop --command just test-vitest with targeted nix profile install for pnpm, node, and just, then plain just test-vitest
  • CI pkg-pr-new job — add node + bun — both runtimes needed for tsdown and ensure-native-binary prepack scripts
  • CI perf jobs — add nodejs_24 — perf scripts may need node alongside existing bun
  • Release workflow — add bun — needed for ensure-native-binary; node stays on setup-node for npm registry auth
  • pnpm-lock.yaml — remove runtime entries — drops the bun@runtime:1.3.14 and node@runtime:24.15.0 package entries and their snapshot stubs

Pullfrog  | View workflow run | Using Big Pickle (free via Pullfrog for OSS) | 𝕏

Pin to the unversioned `pnpm` and `nodejs` attributes rather than `pnpm_11` /
`nodejs_24`. `pnpm` currently resolves to 11.1.1 (same as the explicit alias,
matching the lockfile) and `nodejs` tracks the active LTS, so the dev shell and
CI follow the maintained defaults without hard-coding a major.
@ryoppippi
ryoppippi deleted the branch ci/push-main-only June 11, 2026 15:17
@ryoppippi ryoppippi closed this Jun 11, 2026
@ryoppippi
ryoppippi deleted the chore/provision-node-bun-via-nix branch June 11, 2026 15:20
@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 5e61d0e32857
Base SHA: 0a3391e302b2

This compares the PR package against the configured base package on the same CI runner.

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new 0a3391e302b2 823.1ms 1.072s 78.0ms 3
PR pkg.pr.new 5e61d0e 973.4ms 1.081s 74.0ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: 0a3391e302b2; PR package: 5e61d0e. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 981.6ms 939.6ms 1.04x 732.50 MiB 737.50 MiB 1.01x 1.03 GiB/s 1.07 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 218.5ms 209.6ms 1.04x 91.75 MiB 88.75 MiB 0.97x 4.61 GiB/s 4.80 GiB/s

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 897.1ms 1.12 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 1.043s 988.85 MiB/s 1
codex --offline --json Package wrapper 1.01 GiB 183.4ms 5.49 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 139.7ms 7.21 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 56.6ms 51.4ms 1.10x 43.00 MiB 43.00 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
claude session --offline --json 0.00 MiB 53.0ms 49.8ms 1.07x 43.00 MiB 43.25 MiB 1.01x 0.03 MiB/s 0.03 MiB/s
codex daily --offline --json 0.00 MiB 48.5ms 49.1ms 0.99x 43.00 MiB 43.00 MiB 1.00x 0.02 MiB/s 0.02 MiB/s
codex session --offline --json 0.00 MiB 50.7ms 49.0ms 1.03x 43.00 MiB 43.25 MiB 1.01x 0.02 MiB/s 0.02 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 914.4ms 981.7ms 0.93x 729.25 MiB 734.50 MiB 1.01x 1.10 GiB/s 1.03 GiB/s
codex --offline --json 1.01 GiB 186.2ms 182.9ms 1.02x 93.25 MiB 90.50 MiB 0.97x 5.41 GiB/s 5.51 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB -0.00 KiB 1.00x
installed native package binary 3324.84 KiB 3324.84 KiB +0.00 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 5e61d0e32857
Base SHA: 0a3391e302b2

This compares the Rust PR release binary against the configured base package on the same CI runner.

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new 0a3391e302b2 892.8ms 862.5ms 74.3ms 3
PR pkg.pr.new 5e61d0e 773.9ms 941.5ms 72.0ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: 0a3391e302b2; PR package: 5e61d0e. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 956.1ms 932.3ms 1.03x 740.50 MiB 728.75 MiB 0.98x 1.05 GiB/s 1.08 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 221.2ms 217.1ms 1.02x 87.25 MiB 88.50 MiB 1.01x 4.55 GiB/s 4.64 GiB/s

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 955.0ms 1.05 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 988.2ms 1.02 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 188.9ms 5.33 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 137.3ms 7.33 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 50.5ms 6.3ms 8.04x 43.25 MiB 3.00 MiB 0.07x 0.03 MiB/s 0.25 MiB/s
claude session --offline --json 0.00 MiB 48.6ms 6.4ms 7.61x 43.25 MiB 2.75 MiB 0.06x 0.03 MiB/s 0.24 MiB/s
codex daily --offline --json 0.00 MiB 52.2ms 5.9ms 8.89x 43.25 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.15 MiB/s
codex session --offline --json 0.00 MiB 48.0ms 6.1ms 7.82x 43.25 MiB 2.75 MiB 0.06x 0.02 MiB/s 0.14 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 860.1ms 838.4ms 1.03x 734.00 MiB 724.75 MiB 0.99x 1.17 GiB/s 1.20 GiB/s
codex --offline --json 1.01 GiB 187.9ms 143.6ms 1.31x 89.00 MiB 91.00 MiB 1.02x 5.36 GiB/s 7.01 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 17.32 KiB 17.32 KiB -0.00 KiB 1.00x
installed native package binary 3324.84 KiB 3324.84 KiB +0.00 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

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