I'm working with continuous integration and discovered the npm ci command.
I can't figure what the advantages are of using this command for my workflow.
Is it faster? Does it make the test harder, okay, and after?
I'm working with continuous integration and discovered the npm ci command.
I can't figure what the advantages are of using this command for my workflow.
Is it faster? Does it make the test harder, okay, and after?
From the official documentation for npm ci:
In short, the main differences between using npm install and npm ci are:
- The project must have an existing package-lock.json or npm-shrinkwrap.json.
- If dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock.
- npm ci can only install entire projects at a time: individual dependencies cannot be added with this command.
- If a node_modules is already present, it will be automatically removed before npm ci begins its install.
- It will never write to package.json or any of the package-locks: installs are essentially frozen.
Essentially,
npm install
reads package.json
to create a list of dependencies and uses package-lock.json
to inform which versions of these dependencies to install. If a dependency is not in package-lock.json
it will be added by npm install
.
npm ci
(also known as Clean Install) is meant to be used in automated environments — such as test platforms, continuous integration, and deployment — or, any situation where you want to make sure you're doing a clean install of your dependencies.
It installs dependencies directly from package-lock.json
and uses package.json
only to validate that there are no mismatched versions. If any dependencies are missing or have incompatible versions, it will throw an error.
Use npm install
to add new dependencies, and to update dependencies on a project. Usually, you would use it during development after pulling changes that update the list of dependencies but it may be a good idea to use npm ci
in this case.
Use npm ci
if you need a deterministic, repeatable build. For example during continuous integration, automated jobs, etc. and when installing dependencies for the first time, instead of npm install
.
npm install
npm-shrinkwrap.json
and package-lock.json
(in that order).node_modules
.package.json
or package-lock.json
.
npm i packagename
) it may write to package.json
to add or update the dependency.npm i
) it may write to package-lock.json
to lock down the version of some dependencies if they are not already in this file.npm ci
package-lock.json
or npm-shrinkwrap.json
to be present.package.json
.node_modules
and install all dependencies at once.package.json
or package-lock.json
.While npm ci
generates the entire dependency tree from package-lock.json
or npm-shrinkwrap.json
, npm install
updates the contents of node_modules
using the following algorithm (source):
load the existing node_modules tree from disk clone the tree fetch the package.json and assorted metadata and add it to the clone walk the clone and add any missing dependencies dependencies will be added as close to the top as is possible without breaking any other modules compare the original tree with the cloned tree and make a list of actions to take to convert one to the other execute all of the actions, deepest first kinds of actions are install, update, remove and move
npm install
could write to package.json. Do you know what it could write in here?
npm install package
could modify both package-lock.json
and package.json
, while npm install
whithout arguments would only modify package-lock.json
devDependencies
is controlled by the --production
flag or the NODE_ENV
environment variable, for both npm i
and npm ci
Commented
Feb 17, 2020 at 3:15
ci
in npm ci
is better understood as clean install and not continuous integration.
Commented
Mar 5, 2021 at 18:31
npm ci
will delete any existing node_modules
folder and relies on the package-lock.json
file to install the specific version of each package. It is significantly faster than npm install because it skips some features. Its clean state install is great for ci/cd pipelines and docker builds! You also use it to install everything all at once and not specific packages.
You should use them in different situations.
npm install
is great for development and in the CI when you want to cache the node_modules
directory.
When to use this? You can do this if you are making a package for other people to use (you do NOT include node_modules
in such a release). Regarding the caching, be careful, if you plan to support different versions of Node.js
remember that node_modules
might have to be reinstalled due to differences between the Node.js
runtime requirements. If you wish to stick to one version, stick to the latest LTS
.
npm ci
should be used when you are to test and release a production application (a final product, not to be used by other packages) since it is important that you have the installation be as deterministic as possible, this install will take longer but will ultimately make your application more reliable (you do include node_modules
in such a release). Stick with LTS
version of Node.js
.
npm i
and npm ci
both utilize the npm cache if it exists, this cache lives normally at ~/.npm
.
Also, npm ci
respects the package-lock.json
file. Unlike npm install
, which rewrites the file and always installs new versions.
Bonus: You could mix them depending on how complex you want to make it. On feature branches in git
you could cache the node_modules
to increase your teams productivity and on the merge request and master branches rely on npm ci
for a deterministic outcome.
npm i
should be used over npm ci
except when you want to update your dependencies. npm ci
is always better because deterministic behaviour is always better
npm i
caches as it is quicker, npm ci
is slower since it does a full reinstall. They are both useful.
Commented
Mar 23, 2021 at 9:15
npm ci
is just as fast if every package is in the npm cache
npm ci
is significantly slower even when done repeatedly, with a local NPM cache: npm install
is about 2s, npm ci
16s when run for the same project. After a cache clear they're the same. We desperately need something that would install from package-lock but don't start by deleting node_modules: github.com/npm/cli/issues/564
node_modules
is a feature as I've seen it happen that developers had some custom changes in there and were wondering why it wouldn't work on production. I always prefer a command having repeatedly the exact same outcome over the seemingly faster one. Yet just the fact that npm install
might mutate the package-lock.json
is a really bad default for a dependency manager and also is a huge win for npm ci
. I always use ci
for pure installation even on my development machine, and install
only for when I want to update or add a new dependency.
Commented
May 4, 2022 at 10:56
npm ci
- install exactly what is listed in package-lock.json.
npm install
- without changing any versions in package.json, use package.json to write package-lock.json, then install exactly what is listed in package-lock.jsonnpm update
- similar to npm install
but will also install updates for "blurred version" stuff (e.g. *
, ^1.2.3
)npx npm-check-updates -u; npm install
- Will try to update absolutely everything to the latest version. Be careful of breaking changes when using this one.Or said a different way, npm ci
changes 0 package files, npm install
and npm update
change 1 package file (package-lock.json), and npx npm-check-updates -u; npm install
changes 2 package files (package.json and package-lock.json).
The documentation you linked had the summary:
In short, the main differences between using npm install and npm ci are:
- The project must have an existing package-lock.json or npm-shrinkwrap.json.
- If dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock.
- npm ci can only install entire projects at a time: individual dependencies cannot be added with this command.
- If a node_modules is already present, it will be automatically removed before npm ci begins its install.
- It will never write to package.json or any of the package-locks: installs are essentially frozen.
The commands are very similar in functionality however the difference is in the approach taken to install the dependencies specified in your package.json
and package-lock.json
files.
npm ci
performs a clean install of all the dependencies of your app whereas npm install
may skip some installations if they already exist on the system. A problem may arise if the version already installed on the system isn't the one your package.json
intended to install i.e. the installed version is different from the 'required' version.
Other differences would be that npm ci
never touches your package*.json
files. It will stop installation and show an error if the dependency versions do not match in the package.json
and package-lock.json
files.
You can read a much better explanation from the official docs here.
Additionally, you may want to read about package locks here.
It is worth having in mind that light node docker images like alpine do not have Python installed which is a dependency of node-gyp
which is used by npm ci
.
I think it's a bit opinionated that in order to have npm ci
working you need to install Python as dependency in your build.
More info here Docker and npm - gyp ERR! not ok
react-scripts
not due to npm ci
from what I can find there no dependency on python
in npm ci
Commented
Aug 5, 2021 at 2:36
It does a clean install, use it in situations where you would delete node_modules and re-run npm i
.
I have no idea why some people think it's short for "continuous integration". There is an npm install
command that can be run as npm i
and an npm clean-install
command that can be run as npm ci
.
npm install is the command used to install the dependencies listed in a project's package.json file, while npm ci is a command that installs dependencies from a package-lock.json or npm-shrinkwrap.json file. The npm ci command is typically used in continuous integration (CI) environments, where the package-lock.json or npm-shrinkwrap.json file is checked into version control and should not be modified. Because npm ci installs dependencies from a locked file, it is a faster and more reliable way to install dependencies than npm install, which could install different versions of dependencies based on the state of the package.json file.