Make npm install fast and handy.
- Node.js >= 20.x
- Python >= 3.x
$ npm i -g npminstallIt is integrated in cnpm.
$ npm i -g cnpm # will use npminstall $ cnpm installUsage: npminstall npminstall <pkg> npminstall <pkg>@<tag> npminstall <pkg>@<version> npminstall <pkg>@<version range> npminstall <alias>@npm:<name> npminstall <folder> npminstall <tarball file> npminstall <tarball url> npminstall <git:// url> npminstall <github username>/<github project> Can specify one or more: npm install ./foo.tgz bar@stable /some/folder If no argument is supplied, installs dependencies from ./package.json. Options: --production: won't install devDependencies --save, --save-dev, --save-optional: save installed dependencies into package.json -g, --global: install devDependencies to global directory which specified in `$ npm config get prefix` -r, --registry: specify custom registry -c, --china: specify in china, will automatically using chinese npm registry and other binary's mirrors -d, --detail: show detail log of installation --trace: show memory and cpu usages traces of installation --ignore-scripts: ignore all preinstall / install and postinstall scripts during the installation --no-optional: ignore optionalDependencies during the installation --forbidden-licenses: forbit install packages which used these licenses --engine-strict: refuse to install (or even consider installing) any package that claims to not be compatible with the current Node.js version. --flatten: flatten dependencies by matching ancestors dependencies --registry-only: make sure that all packages are installed from registry. Any package that is installed from remote(e.g.: git, remote url) will lead to a failure of installation. --cache-strict: use disk cache even on production envUsage: npmuninstall <pkg> npmuninstall <pkg>@<version> npmuninstall <pkg>@<version> [<pkg>@<version>] npminstall <alias>@npm:<name>Usage: npmlink <folder>$ npm install npminstall --saveconst npminstall = require('npminstall'); (async () => { await npminstall({ // install root dir root: process.cwd(), // optional packages need to install, default is package.json's dependencies and devDependencies // pkgs: [ // { name: 'foo', version: '~1.0.0' }, // ], // install to specific directory, default to root // targetDir: '/home/admin/.global/lib', // link bin to specific directory (for global install) // binDir: '/home/admin/.global/bin', // registry, default is https://registry.npmjs.org // registry: 'https://registry.npmjs.org', // debug: false, // storeDir: root + 'node_modules', // ignoreScripts: true, // ignore pre/post install scripts, default is `false` // forbiddenLicenses: forbit install packages which used these licenses }); })().catch(err => { console.error(err); });- all types of npm package
- a) a folder containing a program described by a package.json file (
npm install file:eslint-rule) - b) a gzipped tarball containing (a) (
npm install ./rule.tgz) - c) a url that resolves to (b) (
npm install https://github.com/indexzero/forever/tarball/v0.5.6) - d) a @ that is published on the registry with (c)
- e) a @ (see npm-dist-tag) that points to (d)
- f) a that has a "latest" tag satisfying (e)
- g) a that resolves to (a) (
npm install git://github.com/timaschew/cogent#fix-redirects)
- a) a folder containing a program described by a package.json file (
- All platform support
- global install (
-g, --global) -
preinstall,install,postinstallscripts - node-gyp@9, only support Python@3
- node-pre-gyp
- bin (yo@1.6.0, fsevents@1.0.6)
- scoped package
- bundleDependencies / bundledDependencies (node-pre-gyp@0.6.19, fsevents@1.0.6)
- optionalDependencies (pm2@1.0.0)
- peerDependencies (co-defer@1.0.0, co-mocha@1.1.2, estraverse-fb@1.3.1)
- deprecate message
-
--productionmode -
save,save-dev,save-optional - support
ignore-scripts - uninstall
- resolutions
- npm alias
- npm workspaces
This project is inspired by pnpm, and has a similar store structure like pnpm. You can read pnpm vs npm to see the different with npm.
- You can't install from shrinkwrap(and don't want to support for now).
- Peer dependencies are a little trickier to deal with(see rule 1 below).
- You can't publish npm modules with bundleDependencies managed by npminstall(because of rule 2 below).
npminstallwill collect all postinstall scripts, and execute them until all dependencies installed.- If last install failed, better to cleanup node_modules directory before retry.
Two rules:
- The latest version of modules will link at
options.storeDir'snode_modules. - Module's dependencies will link at module's
node_modules.
e.g.:
- app:
{ "dependencies": { "debug": "2.2.0" } }(root) - debug@2.2.0:
{ "dependencies": { "ms": "0.7.1" } }
app/ ├── package.json └── node_modules ├── _debug@2.2.0@debug │ ├── node_modules │ │ └── ms -> ../../_ms@0.7.1@ms ├── _ms0.7.1@ms ├── debug -> _debug@2.2.0@debug └── ms -> _ms@0.7.1@ms # for peerDependenciesnpminstall will always try to install the maximal matched version of semver:
root/ koa@1.1.0 mod/ koa@~1.1.0 # will install two different version of koa when use npminstall. you can enable flatten mode by --flatten flag, in this mod, npminstall will try to use ancestors' dependencies to minimize the dependence-tree.
root/ koa@1.1.0 mod/ koa@~1.1.0 root/ koa@1.1.0 mod/ koa@^1.1.0 # both the same version: 1.1.0 root/ koa@~1.1.0 mod/ koa@^1.1.0 # both the same version: 1.1.2 root/ mod/ koa@^1.1.0 moe/ koa@~1.1.0 # two different versions npminstall will always treat n.x and n.m.x as flattened
root/ koa@1.1.0 mod/ koa@1.1.x both the same version: 1.1.0 root/ koa@~1.1.0 mod/ koa@1.x both the same version: 1.1.2 support selective version resolutions like yarn. which lets you define custom package versions inside your dependencies through the resolutions field in your package.json file.
resolutions also supports npm alias. It's a workaround feature to fix some archived/inactive/ package by uploading your own bug-fixed version to npm registry.
see use case at unittest package.json.
https://github.com/cnpm/npminstall-benchmark
- npminstall@1.2.0
- pnpm@0.18.0
- npm@2.14.12
| cli | real | user | sys |
|---|---|---|---|
| npminstall | 0m10.908s | 0m8.733s | 0m4.282s |
| npminstall with cache | 0m8.815s | 0m7.492s | 0m3.644s |
| npminstall --no-cache | 0m10.279s | 0m8.255s | 0m3.932s |
| pnpm | 0m13.509s | 0m11.650s | 0m4.443s |
| npm | 0m28.171s | 0m26.085s | 0m8.219s |
| npm with cache | 0m20.939s | 0m19.415s | 0m6.302s |
see https://github.com/pnpm/pnpm#benchmark
npminstall babel-preset-es2015 browserify chalk debug minimist mkdirp real 0m8.929s user 0m5.606s sys 0m2.913spnpm i babel-preset-es2015 browserify chalk debug minimist mkdirp real 0m12.998s user 0m8.653s sys 0m3.362snpm i babel-preset-es2015 browserify chalk debug minimist mkdirp real 1m4.729s user 0m55.589s sys 0m23.135sMade with contributors-img.