Skip to content

fix(cli): ship onnxruntime-node + tokenizers natives in linux-x64 tarball - #3921

Merged
saddlepaddle merged 1 commit into
mainfrom
cli-linux-tokenizers-onnx
Apr 30, 2026
Merged

saddlepaddle merged 1 commit into
mainfrom
cli-linux-tokenizers-onnx

Conversation

@saddlepaddle

@saddlepaddle saddlepaddle commented Apr 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The published v0.2.0 linux-x64 tarball crashes immediately on superset start:

Error: Cannot find module './tokenizers.linux-x64-gnu-xcjh3jwk.node'
Require stack:
- /home/sprite/superset/lib/host-service.js

Verified by superset start on a fresh Ubuntu 25.10 install of the published tarball — host service exits before binding a port.

Root cause

The host-service bundle (built via bun run build:host) externalizes better-sqlite3, node-pty, @parcel/watcher, and libsql so their .node loaders resolve at runtime from lib/node_modules/. But it was bundling @anush008/tokenizers and onnxruntime-node (pulled in transitively through @mastra/fastembed → fastembed), so Bun's bundler statically processed their native-loader require()s and emitted content-hashed asset references — without the matching .node files alongside the bundle.

Fix

Same pattern that already works for the other native deps:

  1. packages/host-service/build.ts — add onnxruntime-node and @anush008/tokenizers (+ platform variants) to the external list. fastembed and @mastra/fastembed stay bundled (pure JS, no .node files of their own).
  2. packages/cli/scripts/build-dist.ts — add onnxruntime-node and @anush008/tokenizers to NATIVE_PACKAGES so they're copied whole into lib/node_modules/. Add @anush008/tokenizers-{darwin-universal,linux-x64-gnu} to TARGET_NATIVE_PACKAGES so each target tarball ships only the binding it needs.

Verification

Built locally inside a docker container that mirrors CI's ubuntu-latest runner exactly (ubuntu:24.04 base, bun 1.3.11, node 22.13.0, bun install --frozen --ignore-scripts → npx node-gyp rebuild for node-pty → npm rebuild better-sqlite3 @parcel/watcher → bun run build:dist --target=linux-x64), pushed to a fresh sprite Ubuntu 25.10 box, ran superset start:

[host-service:db] Initialized at /home/sprite/.superset/host/.../host.db
[host-service] listening on http://localhost:40073
●  Connected to relay — machine is now accessible.
[host-service] registered as host a5b47dedad57a63d234ffff6753c74df
[host-service:tunnel] connected to relay

mcp__superset__hosts_list confirms the host now reports online: true from the cloud's perspective. CI's existing smoke test in build-cli.yml would also catch a regression here:

for (const m of ["better-sqlite3", "node-pty", "@parcel/watcher", "libsql"]) {
  require(m);
}

Worth extending that loop to include onnxruntime-node and @anush008/tokenizers so future drift gets caught at build time. (Not in this PR — separate concern, easy follow-up.)

Caveats

  • linux-arm64 doesn't ship @anush008/tokenizers — no published linux-arm64-gnu binding from the upstream package. Code paths that call fastembed will fail at runtime on linux-arm64; non-fastembed paths still work. Adding arm64 support requires either upstream binaries or building from source.
  • Desktop unaffected — host-service/build.ts is only invoked by the CLI's build-dist.ts (verified via grep). Desktop bundles host-service through electron-vite + electron-builder, separate path.

Test plan

  • CI build-cli.yml produces a green linux-x64 artifact
  • On a fresh Ubuntu host: extract tarball, run superset start — expect the host service to come up and register with the relay
  • Verify darwin-arm64 + darwin-x64 artifacts still work (we added darwin-universal to their NATIVE_PACKAGES too)

Summary by CodeRabbit

  • Chores
    • Updated build configuration to improve native dependency bundling and module externalization.

…ux-x64 tarball

The published v0.2.0 linux-x64 tarball crashed on `superset start` with:

  Error: Cannot find module './tokenizers.linux-x64-gnu-xcjh3jwk.node'
  Require stack: lib/host-service.js

Root cause: Bun.build was statically processing native-loader requires
inside @anush008/tokenizers/index.js (and onnxruntime-node) and emitting
content-hashed asset references in host-service.js. The matching .node
files weren't being copied alongside the bundle, so the require failed
at runtime.

Fix mirrors how better-sqlite3, node-pty, @parcel/watcher, libsql are
already handled:

- host-service/build.ts: mark onnxruntime-node and @anush008/tokenizers
  (+ platform variants) as external. Pure-JS wrappers (fastembed,
  @mastra/fastembed) keep getting bundled — they only have peer-dep
  references that the runtime require() resolves from lib/node_modules.
- cli/scripts/build-dist.ts: add onnxruntime-node and @anush008/tokenizers
  to NATIVE_PACKAGES so they're copied whole. Add the platform-specific
  @anush008/tokenizers-{darwin-universal,linux-x64-gnu} subpackages to
  TARGET_NATIVE_PACKAGES per target.

Verified end-to-end on an Ubuntu 25.10 Fly machine via a build mirroring
CI exactly: ubuntu:24.04 docker, bun 1.3.11, node 22.13.0, full install
script. host-service comes up, registers with the relay, host appears
online to the cloud API.

Note: linux-arm64 doesn't ship @anush008/tokenizers (no published
linux-arm64-gnu binding). fastembed-dependent code paths will fail
there at runtime; non-fastembed paths still work.
@coderabbitai

coderabbitai Bot commented Apr 30, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 40997c8b-b1bf-4654-a937-72b1973457b4

📥 Commits

Reviewing files that changed from the base of the PR and between c5336f6 and bc2ed5b.

📒 Files selected for processing (2)
  • packages/cli/scripts/build-dist.ts
  • packages/host-service/build.ts

📝 Walkthrough

Walkthrough

Build configuration for CLI and host-service packages is updated to explicitly manage native addon dependencies. onnxruntime-node and @anush008/tokenizers packages are now treated as bundled or externalized dependencies, with platform-specific variants added for macOS and Linux targets.

Changes

Cohort / File(s) Summary
CLI Build Distribution
packages/cli/scripts/build-dist.ts
Adds onnxruntime-node and @anush008/tokenizers to native addon bundling configuration. Extends per-target optional native dependency mappings for macOS (arm64/x64) and linux-x64 with platform-specific @anush008/tokenizers variants.
Host-Service Build Configuration
packages/host-service/build.ts
Expands the external list in Bun.build to include libsql, onnxruntime-node, and platform-specific @anush008/tokenizers packages, altering which modules are externalized versus bundled at runtime.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 Hop hop, the packages align,
Native addons bundled so fine,
Platform paths for Darwin and Linux too,
Build scripts dancing, old and new! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main fix: shipping native binaries for onnxruntime-node and tokenizers in the linux-x64 tarball to resolve the module resolution crash.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering root cause, fix, verification steps, and caveats; it exceeds the template requirements with detailed technical context.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cli-linux-tokenizers-onnx

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 6/8 reviews remaining, refill in 9 minutes and 57 seconds.

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

@greptile-apps

greptile-apps Bot commented Apr 30, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a crash-on-start regression in the published linux-x64 CLI tarball by externalizing onnxruntime-node and @anush008/tokenizers from the Bun host-service bundle and copying them as native addon packages into the distribution. It also silently corrects the same class of bug for libsql, which was already in NATIVE_PACKAGES but was not externalized in build.ts, meaning Bun had been statically processing its native-loader requires with the same content-hashed asset problem.

Confidence Score: 5/5

Safe to merge — the fix follows the established native-addon externalization pattern exactly, is verified end-to-end, and all remaining findings are P2 style/documentation notes.

Both changed files apply a well-understood pattern that already works for better-sqlite3/node-pty. The only open items are a stale JSDoc comment and an undocumented-but-correct libsql side-fix, neither of which affects runtime behavior. The PR author verified the fix on a fresh Ubuntu 25.10 install.

No files require special attention.

Important Files Changed

Filename Overview
packages/host-service/build.ts Adds onnxruntime-node, @anush008/tokenizers (all platform variants), and libsql to the Bun external list, preventing the bundler from statically inlining their native-loader requires. Stale JSDoc comment still lists only the original two externals.
packages/cli/scripts/build-dist.ts Adds onnxruntime-node and @anush008/tokenizers to NATIVE_PACKAGES (whole-package copy for all targets) and adds platform-specific @anush008/tokenizers-{darwin-universal,linux-x64-gnu} bindings to TARGET_NATIVE_PACKAGES. linux-arm64 intentionally omits the tokenizers binding (documented limitation).

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["bun run build:dist --target=linux-x64"] --> B["buildHostService()\nbun run build:host"]
    B --> C{"Bun.build externals"}
    C -->|externalized| D["better-sqlite3\nnode-pty\n@parcel/watcher\nlibsql ✨\nonnxruntime-node ✨\n@anush008/tokenizers ✨"]
    C -->|bundled pure-JS| E["fastembed\n@mastra/fastembed"]
    B --> F["dist/host-service.js\n(no content-hashed .node refs)"]
    A --> G["copyNativePackages()"]
    G --> H["NATIVE_PACKAGES\nbetter-sqlite3, node-pty\n@parcel/watcher, libsql\nonnxruntime-node ✨\n@anush008/tokenizers ✨"]
    G --> I["TARGET_NATIVE_PACKAGES linux-x64"]
    I --> J["@libsql/linux-x64-gnu\n@parcel/watcher-linux-x64-glibc\n@anush008/tokenizers-linux-x64-gnu ✨"]
    H --> K["lib/node_modules/"]
    J --> K
    F --> L["lib/host-service.js"]
    K --> M["superset-linux-x64.tar.gz"]
    L --> M
Loading

Comments Outside Diff (1)

  1. packages/host-service/build.ts, line 1-6 (link)

    P2 Stale top-of-file comment

    The JSDoc still says "Native addons (better-sqlite3, node-pty) are marked external" but the list now covers six packages. A quick update prevents future contributors from being confused about which deps are externalized.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: packages/host-service/build.ts
    Line: 1-6
    
    Comment:
    **Stale top-of-file comment**
    
    The JSDoc still says "Native addons (better-sqlite3, node-pty) are marked external" but the list now covers six packages. A quick update prevents future contributors from being confused about which deps are externalized.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
packages/host-service/build.ts:1-6
**Stale top-of-file comment**

The JSDoc still says "Native addons (better-sqlite3, node-pty) are marked external" but the list now covers six packages. A quick update prevents future contributors from being confused about which deps are externalized.

```suggestion
/**
 * Bundles the host-service entry point into a single JS file that can be
 * executed by a standalone Node.js runtime. Native addons (better-sqlite3,
 * node-pty, @parcel/watcher, libsql, onnxruntime-node, @anush008/tokenizers)
 * are marked external and must be resolved at runtime from
 * lib/node_modules/ in the distribution bundle.
 */
```

### Issue 2 of 2
packages/host-service/build.ts:24
**`libsql` externalization fix is undocumented**

`libsql` was already in `NATIVE_PACKAGES` (and therefore copied into the tarball), but was not externalized in the Bun build before this PR. That means Bun previously statically processed `libsql`'s native-loader `require()` calls, producing the same class of content-hashed asset reference bug that this PR fixes for `onnxruntime-node`/`@anush008/tokenizers`. Adding it to `external` here is the right fix, but it isn't mentioned in the PR description — worth calling out so reviewers know this is intentional and that any `libsql` crash on a prior release would also be resolved by this change.

Reviews (1): Last reviewed commit: "fix(cli): ship onnxruntime-node + @anush..." | Re-trigger Greptile

"better-sqlite3",
"node-pty",
"@parcel/watcher",
"libsql",

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.

P2 libsql externalization fix is undocumented

libsql was already in NATIVE_PACKAGES (and therefore copied into the tarball), but was not externalized in the Bun build before this PR. That means Bun previously statically processed libsql's native-loader require() calls, producing the same class of content-hashed asset reference bug that this PR fixes for onnxruntime-node/@anush008/tokenizers. Adding it to external here is the right fix, but it isn't mentioned in the PR description — worth calling out so reviewers know this is intentional and that any libsql crash on a prior release would also be resolved by this change.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/host-service/build.ts
Line: 24

Comment:
**`libsql` externalization fix is undocumented**

`libsql` was already in `NATIVE_PACKAGES` (and therefore copied into the tarball), but was not externalized in the Bun build before this PR. That means Bun previously statically processed `libsql`'s native-loader `require()` calls, producing the same class of content-hashed asset reference bug that this PR fixes for `onnxruntime-node`/`@anush008/tokenizers`. Adding it to `external` here is the right fix, but it isn't mentioned in the PR description — worth calling out so reviewers know this is intentional and that any `libsql` crash on a prior release would also be resolved by this change.

How can I resolve this? If you propose a fix, please make it concise.

@github-actions

github-actions Bot commented Apr 30, 2026 •

Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch

Thank you for your contribution! 🎉

@saddlepaddle
saddlepaddle merged commit 7c4f76a into main Apr 30, 2026
15 checks passed
@saddlepaddle saddlepaddle mentioned this pull request Apr 30, 2026
4 tasks
saddlepaddle added a commit that referenced this pull request Apr 30, 2026
Patch release for the linux-x64 startup crash (PRs #3921, #3920, #3922
since v0.2.0). Push cli-v0.2.1 after this lands to fire the release
pipeline.
github-actions Bot added a commit that referenced this pull request May 1, 2026
Adds a configuration test that asserts both build pipelines list
@anush008/tokenizers-linux-arm64-gnu alongside the linux-x64 binding
fixed in #3921. The reproduction fails today because the package is
omitted from:

- TARGET_NATIVE_PACKAGES["linux-arm64"] in packages/cli/scripts/build-dist.ts
- the Bun.build external array in packages/host-service/build.ts

Also wires up `bun test` for @superset/cli so the reproduction runs
under turbo. A real fix is blocked upstream — @anush008/tokenizers@0.0.0
does not declare the arm64 variant in optionalDependencies, and
@anush008/tokenizers-linux-arm64-gnu@0.0.0 is not published on npm.

Refs #3951
saddlepaddle added a commit that referenced this pull request May 1, 2026
…rball (#3960)

The linux-arm64 CLI tarball crashed on `superset start` with
`Cannot find module '@anush008/tokenizers-linux-arm64-gnu'`. #3921 added
the binding for linux-x64 but missed arm64. Three layers had to line up:

1. The build script needed the binding in TARGET_NATIVE_PACKAGES and the
   host-service bundler needed it as an external.
2. `@anush008/tokenizers@0.0.0` (pinned via fastembed → ^0.0.0) lists no
   linux-arm64 variant in optionalDependencies, so even with (1) bun
   couldn't resolve it.
3. `@anush008/tokenizers-linux-arm64-gnu@0.0.0` doesn't exist on npm
   (only 0.5.0 and 0.6.0 are published).

Pin the 0.6.0 binding directly as an optionalDependency on host-service
so bun installs it on linux-arm64 and skips it elsewhere via os/cpu
filtering. The 0.6.0 native binary is ABI-compatible with the 0.0.0 JS
loader for the surface fastembed uses (Tokenizer.fromString,
setTruncation, setPadding, AddedToken, async encode, getIds, getTokens).

Verified end-to-end in linux/arm64 docker: `bun install --frozen` picks
up the binding, `build:dist --target=linux-arm64` ships it in
lib/node_modules, the bundled Node loads `require("@anush008/tokenizers")`
cleanly, and `superset-host` boots past the previous MODULE_NOT_FOUND.

Closes #3951.
@Kitenite
Kitenite deleted the cli-linux-tokenizers-onnx branch May 6, 2026 04:51
MocA-Love added a commit to MocA-Love/superset that referenced this pull request May 25, 2026

This branch was previously deployed

1 inactive deployment
preview — bc2ed5b8 Deployed Apr 30, 2026 by saddlepaddle via Deploy Docs #4644
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