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:
cd myapp npm i chalk
And populate your main file
const chalk = require("chalk"); console.log(chalk.blue.bgRed.bold("Hello world!"));
Or we can
ncc build it for production:
ncc implements a
go-style API and design philosophy. Compiling a program should be intuitive, single-command, zero-configuration.
ncc helpor check out the api docs.
nccby extracting the best practices out of our
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:
ncc makes deployment faster and more secure, by only shipping the necessary code to production.
nccdevelopment, it used to bundle webpack as a regular npm dependency. It eventually became good enough to self-host.
We can now compare the installation duration of the non-
In stark contrast to installing the
ncc version (usually 5-10x faster):
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.
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 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:
git pull node my-program
This is because after
git pull the dependencies (
package-lock.json) might have changed.
However, the following will always be predictable and safe:
git pull ncc run my-program
It addresses important gaps in the Node.js ecosystem (such as static typing and JSX support). Crucially, we can add it onobtrusively 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:
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
nccgets remarkably close to the native
nodesemantics (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 installtion (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.
nccoutputs scripts (text),
pkgoutputs executables (binary).
In some cases you will want to use them together, and in others, independently.