ncc
Compile a Node.js project into a single file. Supports TypeScript, binary addons, dynamic requires.
by vercelJavaScript
Commit activity
Last 12 weeks · 3 commits
Community health
3 of 6 standards met
Recent PRs & issues
Summary Port ncc's internal bundling pipeline from webpack to Rspack while preserving the CLI and CommonJS programmatic API. Keep resolver fallback, native asset relocation, TypeScript compilation, and runtime error behavior compatible with the existing fixtures. The programmatic entry now loads as ordinary CommonJS so Rspack receives RegExp loader conditions from the correct JavaScript realm. This fixes incorrect loader selection under Jest and lets JSON use Rspack's native JSON handling without the relocator workaround. The CLI and supporting loaders retain their V8 caches. TypeScript diagnostics and program state live in per-compilation WeakMaps. Type-only source files are registered as watch dependencies, and regression coverage uses a real TypeScript program across source directories. Modules that relocate assets rerun instead of restoring incomplete persistent-cache state: the relocator's paths, permissions, symlinks, and filename allocation are JavaScript compilation side effects that Rspack does not restore with asset contents. Other modules remain cacheable. Cold/warm regressions cover bundled JavaScript sub-assets, executable permissions, and symlinks. Remove the integration suite's coverage-only so coverage actually finishes all suites. Regenerated output fixtures are isolated in a separate commit; their changes are module IDs and removal of a duplicate commented shebang. Validation Validated on macOS arm64 with Node 24.4.1 and Corepack pnpm 10.33.0: All 28 unit fixtures pass. The full suite and complete coverage run each pass all 149 tests across five suites. Validation uses an isolated cache because the unchanged development package version can retain artifacts from earlier local builds. The full run reuses the unit run's cache, and the dedicated regressions explicitly compare cold and warm builds. Ripwire navigation and contract checks found no changed loader contract. Its scoped quality delta has no blocking findings; adding TypeScript watch dependencies produces minor complexity/length increases. The static test gate cannot trace the dynamically loaded Rspack loader, which is exercised by the end-to-end regressions and full suites above. The Linux/Windows and Node 22/26 matrix was not run locally; those checks remain for CI. The symlink regression skips Windows because creating file symlinks there requires privileges not guaranteed by the test environment. Remaining upstream constraint The resolver still uses the agreed adaptation. Avoiding its extra resolution requires Rspack to expose a JavaScript hook for recovering from resolution failures, tracked in https://github.com/web-infra-dev/rspack/issues/14640. This PR does not claim that upstream limitation is resolved.
Fixes #1264 : when there's no project-local , fall back to . This is the same fallback had up to 0.24.1. In , this is the compiler bundled into . Webpack has already loaded that module as the loader, so it isn't evaluated a second time. From (coverage runs), re-exports the devDependency, so behaviour there doesn't change. : copy TypeScript's lib files to instead of . Since TypeScript 5.0, looks for them next to , which for the bundled compiler is . Without this, type-checking with the built-in compiler fails with . The files and the package size stay the same; only the directory changes. : a new test copies to a temp directory outside the repo, so can't be resolved from ncc's location (as with a global install). It builds with pointing nowhere and expects the build to succeed with the built-in compiler. The existing "ncc built-in" test can't catch this bug, because inside the repo finds the repo's own . The new test is skipped under coverage, which runs from , where there is no bundle. A project's own is still used first. This only changes what happens when there isn't one. Verification Environment: macOS, Node 26.3.1. Setup: , , . Command: Result: On , the test fails with the issue's error (). With only the change, it fails with . With both changes, it passes (). Command: Result: This branch: , . plus only the new test: . The only failure is the new test. An earlier full run on this branch reported . The failure was exceeding its 30 s timeout. That test watch-builds twilio, with no TypeScript involved. It passed when run alone (24.8 s) and in the run above. On it took 23.7 s of its 30 s budget. Command: (runs the CLI tests from ) Result: Manual check of the reported scenario: I packed the build with and installed it with , in a directory tree with no package anywhere. In a project (the issue's case), prints and runs the program. The published 0.45.0 fails in the same setup with the issue's error. Type errors are still reported (, exit code 1). still works, and still prints nothing. A project with its own still uses it ().
Summary document what emits and how it can reduce startup work explain which files must be deployed together clarify the Windows, packaged executable, and ES module limitations Verification built and ran a CommonJS sample with ; verified the loader, bundled source, and cache outputs built an ES module sample with the same option; verified that ncc emitted a regular ES module build without cache files Fixes #1182
Recent fixes
Repository: vercel/ncc. Description: Compile a Node.js project into a single file. Supports TypeScript, binary addons, dynamic requires. Stars: 9842, Forks: 326. Primary language: JavaScript. Languages: JavaScript (97.9%), TypeScript (1.1%), Shell (0.4%), Python (0.3%), C++ (0.3%). License: MIT. Homepage: https://npmjs.com/@vercel/ncc Latest release: 0.45.0 (2mo ago). Open PRs: 25, open issues: 197. Last activity: 2mo ago. Community health: 75%. Top contributors: guybedford, dependabot[bot], styfle, rauchg, timneutkens, sokra, huozhi, ijjk, TooTallNate, igorklopov and others.