Appearance
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:#fffPhases
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:
| Strategy | Consumer needs Rust? | Best for |
|---|---|---|
| Prebuilds | No | Public libraries. Build one binary per platform/arch in CI; resolve the right one at install. |
| Compile on install | Yes | Internal 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.jsonmetadata 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.