Today we are thrilled to introduce
, a simple Node.js CLI program and API for compiling Node.js projects into a
Inspired by native compiler toolchains, such as
, that export a static
ELF binary file
will output a self-contained script that
bundles all its dependencies
npm i -g @zeit/ncc
It will download the
ncc compiler, which has been compiled with
Let's create a project and add a dependency:
npm i chalk
And populate your main file
const chalk = require ( "chalk" ) ;
console . log (chalk .blue .bgRed . bold ( "Hello world!" ) ) ;
We compile and run in one go
Or we can
ncc build it for production:
We output the final version to the
ncc implements a
go-style API and design philosophy. Compiling a program should be intuitive, single-command, zero-configuration.
For more usage information, run
or check out the
by extracting the best practices out of our
Deploying a very large dependency tree in just
The entire bundle of code
actually used by our entrypoint amounts to 950kb, which considers
graphql and all their sub-dependencies.
node_modules alone amounts to
35 times the size of our bundle:
It is said that
node_modules is one of the
heaviest objects in the universe.
ncc is therefore
ncc makes deployment faster and more secure, by only shipping the necessary code to production.
In the early days of
development, it used to bundle webpack as a regular npm dependency. It eventually became good enough to
We can now compare the installation duration of the non-
In most of our tests,
ncc would take between 15 and 30 seconds to install
In stark contrast to installing the
ncc version (usually
The installation performance of
ncc is solely bound by your download speed
To demonstrate this, we simply time how long it takes to
This is how long it takes to
src/index.js, where every subsequent
require invokes file-system lookups.
Just importing code can be remarkably slow in Node.js, compared to native programs
When run through
we consistently see
a 50% improvement
in boot-up performance, which will
only get faster
Faster, but there is still a lot of room for improvement
These represent active areas of work following our initial release.
ncc is already quite fast, even though no optimizations have been made.
By leveraging a global cache, we intend for re-runs and re-builds to get incrementally faster with no tradeoffs in safety.
Minification is a remarkably safe operation that has significant boot-up time and package size benefits.
It will be default off for
ncc run and default on for
ncc build. Developers might want to opt out of this feature when debugging programs or dependencies.
ncc will favor safety over maximally optimal minification.
Stack traces that are produced by ncc run should be accurate by default. Developers should be able to opt-into emitting source maps for ncc build production outputs.
go's example, we intend for
ncc to transparently ensure dependencies have been installed, by executing
yarn install or
npm install automatically.
This will help develop more confidently. For example, the following is error-prone:
This is because after
git pull the dependencies (
might have changed.
However, the following will always be predictable and safe:
ncc run my-program
We also look forward to evaluting
cooperating with next-generation
installation approaches like
TypeScript is now being used by up to
50% of Node.js developers
It addresses important gaps in the Node.js ecosystem (such as static typing and JSX support). Crucially, we can add it
unobtrusively by introducing support for the
ncc build my-app.ts
In addition to minification, it's possible to get further boot-up benefits by leveraging the V8 API that emits an image of the parse and compile step.
The contract of
ncc is that it yields an output
directory containing one or more files. Typically it's one, but we also perform static analysis on synchronous filesystem reads.
pdkfit and its dependencies read a lot of files that are bundled with their packages upon initialization:
ncc is capable of emitting dependencies, such as statically analyzable file-system lookups
We plan to use the same technique to support
.node files, making
ncc a complete solution that supports the vast majority of npm modules in the ecosystem out of the box.
ncc run is optional, but it has the following current and future benefits:
Fewer surprises upon
ncc build. While
ncc gets remarkably close to
node semantics (with many
integration tests) from time to time some modules with unusually-dynamic dependencies or filesystem reads could give it trouble. TypeScript support (planned) Transparent dependency installation (planned)
We wanted to focus on a development experience that maximizes productivity, followed the semantics of the Node.js platform out of the box and mirrored the conventions of other well-designed and battle-tested languages.
This means that it should do the right thing out of the box,
with no extra configuration. pkg
is complimentary to
that bundles the Node.js runtime inside. While
outputs scripts (text),
outputs executables (binary).
In some cases you will want to use them together, and in others, independently.