Skip to content

Workflow: Project to npm Pipeline

Fresh 🌱

The full path a Neon module travels from an empty directory to an installable npm package that end users can use without a Rust toolchain.

The flow

flowchart TD
    INIT["npm init neon my-mod"] --> SCAFFOLD["Project: Cargo.toml + package.json + src/lib.rs"]
    SCAFFOLD --> DEV["Write Rust: #[neon::main] + #[neon::export] fns"]
    DEV --> BUILD["npm run build (debug)"]
    BUILD --> TEST{"Works in Node REPL / npm test?"}
    TEST -->|No| DEV
    TEST -->|Yes| REL["npm run build -- --release"]
    REL --> DIST{"Distribution strategy"}
    DIST -->|Library| PREBUILD["Build prebuilds per platform/arch in CI"]
    DIST -->|Internal / simple| ONINSTALL["Compile on user install"]
    PREBUILD --> PUBLISH["npm publish"]
    ONINSTALL --> PUBLISH
    PUBLISH --> CONSUME["Consumer: npm install my-mod"]
    style INIT fill:#10b981,color:#fff
    style REL fill:#6366f1,color:#fff
    style PUBLISH fill:#f59e0b,color:#fff

Phases

1. Scaffold

npm init neon my-mod creates a project that is simultaneously a Rust crate and an npm package. The napi-N feature in Cargo.toml sets the minimum Node-API version.

2. Develop

Write your #[neon::main] entry point and your exported functions. Iterate with the fast debug build (npm run build) and the Node REPL.

3. Verify

Confirm behavior from node (require('.')) and from automated tests (npm test). Because it is an npm package, the normal JS test tooling applies.

4. Release build

npm run build -- --release produces the optimized index.node. Use this for benchmarks and shipping.

5. Choose distribution

This is the decision unique to native modules:

StrategyConsumer needs Rust?Best for
PrebuildsNoPublic libraries. Build one binary per platform/arch in CI; resolve the right one at install.
Compile on installYesInternal tools where every machine already has the toolchain.

6. Publish & consume

npm publish ships the package (directly or via your release pipeline). Consumers run npm install my-mod and, with prebuilds, never compile anything.

Checklist before npm publish

  • [ ] Release build verified
  • [ ] target/ excluded from the published package (files / .npmignore)
  • [ ] package.json metadata complete (name, version, license, repository, main)
  • [ ] Distribution strategy decided and prebuild matrix wired (if a library)

The hard part is the matrix, not the code

Authoring the module is the easy half. The operational complexity of shipping native modules is the prebuild matrix - producing and publishing a binary for every platform and architecture you support. Plan CI for it early. See the Build & Publish SOP.