[node.js] Do I commit the package-lock.json file created by npm 5?

npm 5 was released today and one of the new features include deterministic installs with the creation of a package-lock.json file.

Is this file supposed to be kept in source control?

I'm assuming it's similar to yarn.lock and composer.lock, both of which are supposed to be kept in source control.

This question is related to node.js git npm version-control lockfile

The answer is


Yes, package-lock.json is intended to be checked into source control. If you're using npm 5+, you may see this notice on the command line: created a lockfile as package-lock.json. You should commit this file. According to npm help package-lock.json:

package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.

This file is intended to be committed into source repositories, and serves various purposes:

  • Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.

  • Provide a facility for users to "time-travel" to previous states of node_modules without having to commit the directory itself.

  • To facilitate greater visibility of tree changes through readable source control diffs.

  • And optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages.

One key detail about package-lock.json is that it cannot be published, and it will be ignored if found in any place other than the toplevel package. It shares a format with npm-shrinkwrap.json, which is essentially the same file, but allows publication. This is not recommended unless deploying a CLI tool or otherwise using the publication process for producing production packages.

If both package-lock.json and npm-shrinkwrap.json are present in the root of a package, package-lock.json will be completely ignored.


Yes, it's intended to be checked in. I want to suggest that it gets its own unique commit. We find that it adds a lot of noise to our diffs.


Yes, you SHOULD:

  1. commit the package-lock.json.
  2. use npm ci instead of npm install when building your applications both on your CI and your local development machine

The npm ci workflow requires the existence of a package-lock.json.


A big downside of npm install command is its unexpected behavior that it may mutate the package-lock.json, whereas npm ci only uses the versions specified in the lockfile and produces an error

  • if the package-lock.json and package.json are out of sync
  • if a package-lock.json is missing.

Hence, running npm install locally, esp. in larger teams with multiple developers, may lead to lots of conflicts within the package-lock.json and developers to decide to completely delete the package-lock.json instead.

Yet there is a strong use-case for being able to trust that the project's dependencies resolve repeatably in a reliable way across different machines.

From a package-lock.json you get exactly that: a known-to-work state.

In the past, I had projects without package-lock.json / npm-shrinkwrap.json / yarn.lock files whose build would fail one day because a random dependency got a breaking update.

Those issue are hard to resolve as you sometimes have to guess what the last working version was.

If you want to add a new dependency, you still run npm install {dependency}. If you want to upgrade, use either npm update {dependency} or npm install ${dependendency}@{version} and commit the changed package-lock.json.

If an upgrade fails, you can revert to the last known working package-lock.json.


To quote npm doc:

It is highly recommended you commit the generated package lock to source control: this will allow anyone else on your team, your deployments, your CI/continuous integration, and anyone else who runs npm install in your package source to get the exact same dependency tree that you were developing on. Additionally, the diffs from these changes are human-readable and will inform you of any changes npm has made to your node_modules, so you can notice if any transitive dependencies were updated, hoisted, etc.

And in regards to the difference between npm ci vs npm install:

  • 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.

Note: I posted a similar answer here


Yes, the best practice is to check-in (YES, CHECK-IN)

I agree that it will cause a lot of noise or conflict when seeing the diff. But the benefits are:

  1. guarantee exact same version of every package. This part is the most important when building in different environments at different times. You may use ^1.2.3 in your package.json, but how can u ensure each time npm install will pick up the same version in your dev machine and in the build server, especially those indirect dependency packages? Well, package-lock.json will ensure that. (With the help of npm ci which installs packages based on lock file)
  2. it improves the installation process.
  3. it helps with new audit feature npm audit fix (I think the audit feature is from npm version 6).

I don't commit this file in my projects. What's the point ?

  1. It's generated
  2. It's the cause of a SHA1 code integrity err in gitlab with gitlab-ci.yml builds

Though it's true that I never use ^ in my package.json for libs because I had bad experiences with it.


To the people complaining about the noise when doing git diff:

git diff -- . ':(exclude)*package-lock.json' -- . ':(exclude)*yarn.lock'

What I did was use an alias:

alias gd="git diff --ignore-all-space --ignore-space-at-eol --ignore-space-change --ignore-blank-lines -- . ':(exclude)*package-lock.json' -- . ':(exclude)*yarn.lock'"

To ignore package-lock.json in diffs for the entire repository (everyone using it), you can add this to .gitattributes:

package-lock.json binary
yarn.lock binary

This will result in diffs that show "Binary files a/package-lock.json and b/package-lock.json differ whenever the package lock file was changed. Additionally, some Git services (notably GitLab, but not GitHub) will also exclude these files (no more 10k lines changed!) from the diffs when viewing online when doing this.


Yes, you can commit this file. From the npm's official docs:

package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.

This file is intended to be committed into source repositories[.]


Disable package-lock.json globally

type the following in your terminal:

npm config set package-lock false

this really work for me like magic


Yes, it's a standard practice to commit package-lock.json.

The main reason for committing package-lock.json is that everyone in the project is on the same package version.

Pros:

  • If you follow strict versioning and don't allow updating to major versions automatically to save yourself from backward-incompatible changes in third-party packages committing package-lock helps a lot.
  • If you update a particular package, it gets updated in package-lock.json and everyone using the repository gets updated to that particular version when they take the pull of your changes.

Cons:

  • It can make your pull requests look ugly :)

npm install won't make sure that everyone in the project is on the same package version. npm ci will help with this.


All answers say "YES" but that also depend of the project, the doc says:

One key detail about package-lock.json is that it cannot be published, and it will be ignored if found in any place other than the toplevel package.

This mean that you don't need to publish on npm your package-lock.json for dependency but you need to use package-lock.json in your repo to lock the version of your test dependency, build dependencies…

However, If your are using lerna for managing projects with multiple packages, you should put the package.json only on the root of your repo, not in each subpackage are created with npm init. You will get something like that :

.git
lerna.json
package.json
package-lock.json        <--- here
packages/a/package.json
packages/a/lib/index.js
packages/b/package.json
packages/b/lib/index.js

My use of npm is to generate minified/uglified css/js and to generate the javascript needed in pages served by a django application. In my applications, Javascript runs on the page to create animations, some times perform ajax calls, work within a VUE framework and/or work with the css. If package-lock.json has some overriding control over what is in package.json, then it may be necessary that there is one version of this file. In my experience it either does not effect what is installed by npm install, or if it does, It has not to date adversely affected the applications I deploy to my knowledge. I don't use mongodb or other such applications that are traditionally thin client.

I remove package-lock.json from repo because npm install generates this file, and npm install is part of the deploy process on each server that runs the app. Version control of node and npm are done manually on each server, but I am careful that they are the same.

When npm install is run on the server, it changes package-lock.json, and if there are changes to a file that is recorded by the repo on the server, the next deploy WONT allow you to pull new changes from origin. That is you can't deploy because the pull will overwrite the changes that have been made to package-lock.json.

You can't even overwrite a locally generated package-lock.json with what is on the repo (reset hard origin master), as npm will complain when ever you issue a command if the package-lock.json does not reflect what is in node_modules due to npm install, thus breaking the deploy. Now if this indicates that slightly different versions have been installed in node_modules, once again that has never caused me problems.

If node_modules is not on your repo (and it should not be), then package-lock.json should be ignored.

If I am missing something, please correct me in the comments, but the point that versioning is taken from this file makes no sense. The file package.json has version numbers in it, and I assume this file is the one used to build packages when npm install occurs, as when I remove it, npm install complains as follows:

jason@localhost:introcart_wagtail$ rm package.json
jason@localhost:introcart_wagtail$ npm install
npm WARN saveError ENOENT: no such file or directory, open '/home/jason/webapps/introcart_devtools/introcart_wagtail/package.json'

and the build fails, however when installing node_modules or applying npm to build js/css, no complaint is made if I remove package-lock.json

jason@localhost:introcart_wagtail$ rm package-lock.json 
jason@localhost:introcart_wagtail$ npm run dev

> [email protected] dev /home/jason/webapps/introcart_devtools/introcart_wagtail
> NODE_ENV=development webpack --progress --colors --watch --mode=development

 10% building 0/1 modules 1 active ...

Committing package-lock.json to the source code version control means that the project will use a specific version of dependencies that may or may not match those defined in package.json. while the dependency has a specific version without any Caret (^) and Tilde (~) as you can see, that's mean the dependency will not be updated to the most recent version. and npm install will pick up the same version as well as we need it for our current version of Angular.

Note : package-lock.json highly recommended to commit it IF I added any Caret (^) and Tilde (~) to the dependency to be updated during the CI.


Questions with node.js tag:

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean` jwt check if token expired Using Environment Variables with Vue.js Avoid "current URL string parser is deprecated" warning by setting useNewUrlParser to true Can not find module “@angular-devkit/build-angular” MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017] MySQL 8.0 - Client does not support authentication protocol requested by server; consider upgrading MySQL client npx command not found await is only valid in async function What could cause an error related to npm not being able to find a file? No contents in my node_modules subfolder. Why is that? How to set bot's status Returning data from Axios API Error: EACCES: permission denied, access '/usr/local/lib/node_modules' ReferenceError: fetch is not defined ERROR in Cannot find module 'node-sass' Test process.env with Jest 'react-scripts' is not recognized as an internal or external command NPM Install Error:Unexpected end of JSON input while parsing near '...nt-webpack-plugin":"0' db.collection is not a function when using MongoClient v3.0 When I run `npm install`, it returns with `ERR! code EINTEGRITY` (npm 5.3.0) E: Unable to locate package npm How can the default node version be set using NVM? How to downgrade Node version How to solve npm install throwing fsevents warning on non-MAC OS? How to read file with async/await properly? Angular: Cannot Get / The difference between "require(x)" and "import x" Is there a way to force npm to generate package-lock.json? Angular - ng: command not found MongoError: connect ECONNREFUSED 127.0.0.1:27017 How can I use async/await at the top level? ERROR in ./node_modules/css-loader? Downgrade npm to an older version Node - was compiled against a different Node.js version using NODE_MODULE_VERSION 51 npm install Error: rollbackFailedOptional npm ERR! code UNABLE_TO_GET_ISSUER_CERT_LOCALLY How can I use an ES6 import in Node.js? Node.js: Python not found exception due to node-sass and node-gyp bash: npm: command not found? npm WARN enoent ENOENT: no such file or directory, open 'C:\Users\Nuwanst\package.json' Laravel 5.4 ‘cross-env’ Is Not Recognized as an Internal or External Command

Questions with git tag:

Does the target directory for a git clone have to match the repo name? Git fatal: protocol 'https' is not supported Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) git clone: Authentication failed for <URL> destination path already exists and is not an empty directory SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 GitLab remote: HTTP Basic: Access denied and fatal Authentication How can I switch to another branch in git? VS 2017 Git Local Commit DB.lock error on every commit How to remove an unpushed outgoing commit in Visual Studio? How to know the git username and email saved during configuration? How to add a new project to Github using VS Code git clone error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054 fatal: ambiguous argument 'origin': unknown revision or path not in the working tree HTTP Basic: Access denied fatal: Authentication failed npm notice created a lockfile as package-lock.json. You should commit this file Do I commit the package-lock.json file created by npm 5? Abort a Git Merge key_load_public: invalid format git - remote add origin vs remote set-url origin Visual Studio 2017 - Git failed with a fatal error Get git branch name in Jenkins Pipeline/Jenkinsfile Changing the git user inside Visual Studio Code How to compare different branches in Visual Studio Code Git checkout - switching back to HEAD Clear git local cache Deleting a local branch with Git Rebuild Docker container on file changes Cloning specific branch How to add chmod permissions to file in Git? Git copy changes from one branch to another Git merge with force overwrite Project vs Repository in GitHub How to add a file to the last commit in git? Getting permission denied (public key) on gitlab Delete commit on gitlab gpg failed to sign the data fatal: failed to write commit object [Git 2.10.0] Remove a modified file from pull request Updates were rejected because the tip of your current branch is behind its remote counterpart Can't push to the heroku How to discard local changes and pull latest from GitHub repository In Visual Studio Code How do I merge between two local branches? error: RPC failed; curl transfer closed with outstanding read data remaining Change drive in git bash for windows Checkout Jenkins Pipeline Git SCM with credentials? How to fix git error: RPC failed; curl 56 GnuTLS Trying to pull files from my Github repository: "refusing to merge unrelated histories" Visual Studio Code how to resolve merge conflicts with git? merge one local branch into another local branch Can't push to remote branch, cannot be resolved to branch

Questions with npm tag:

What does 'x packages are looking for funding' mean when running `npm install`? error: This is probably not a problem with npm. There is likely additional logging output above Module not found: Error: Can't resolve 'core-js/es6' Browserslist: caniuse-lite is outdated. Please run next command `npm update caniuse-lite browserslist` ERROR in The Angular Compiler requires TypeScript >=3.1.1 and <3.2.0 but 3.2.1 was found instead DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean` What exactly is the 'react-scripts start' command? On npm install: Unhandled rejection Error: EACCES: permission denied Difference between npx and npm? Local package.json exists, but node_modules missing npx command not found What could cause an error related to npm not being able to find a file? No contents in my node_modules subfolder. Why is that? SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 Error: EACCES: permission denied, access '/usr/local/lib/node_modules' ERROR in Cannot find module 'node-sass' NPM Install Error:Unexpected end of JSON input while parsing near '...nt-webpack-plugin":"0' When I run `npm install`, it returns with `ERR! code EINTEGRITY` (npm 5.3.0) E: Unable to locate package npm Is there a way to force npm to generate package-lock.json? ERROR in ./node_modules/css-loader? Downgrade npm to an older version Node - was compiled against a different Node.js version using NODE_MODULE_VERSION 51 npm WARN ... requires a peer of ... but none is installed. You must install peer dependencies yourself Error: EPERM: operation not permitted, unlink 'D:\Sources\**\node_modules\fsevents\node_modules\abbrev\package.json' npm install Error: rollbackFailedOptional webpack: Module not found: Error: Can't resolve (with relative path) npm ERR! code UNABLE_TO_GET_ISSUER_CERT_LOCALLY npm WARN enoent ENOENT: no such file or directory, open 'C:\Users\Nuwanst\package.json' Laravel 5.4 ‘cross-env’ Is Not Recognized as an Internal or External Command Why does "npm install" rewrite package-lock.json? The term 'ng' is not recognized as the name of a cmdlet Npm Error - No matching version found for What is the role of the package-lock.json? Do I commit the package-lock.json file created by npm 5? What is the difference between npm install and npm run build? How to resolve Nodejs: Error: ENOENT: no such file or directory Node update a specific package Cannot uninstall angular-cli Field 'browser' doesn't contain a valid alias configuration How can I add a .npmrc file? How to solve npm error "npm ERR! code ELIFECYCLE" You seem to not be depending on "@angular/core". This is an error Why is "npm install" really slow? Checking version of angular-cli that's installed? How to specify a port to run a create-react-app based project? Maximum call stack size exceeded on npm install npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected] How to clear cache in Yarn? How to update TypeScript to latest version with npm?

Questions with version-control tag:

How can I switch to another branch in git? Do I commit the package-lock.json file created by npm 5? Project vs Repository in GitHub Remove a modified file from pull request Git push: "fatal 'origin' does not appear to be a git repository - fatal Could not read from remote repository." Git: How to squash all commits on branch git: updates were rejected because the remote contains work that you do not have locally Sourcetree - undo unpushed commits Cannot checkout, file is unmerged Git diff between current branch and master but not including unmerged master commits git push to specific branch How to use Git for Unity3D source control? Correctly ignore all files recursively under a specific folder except for a specific file type How to see the changes in a Git commit? Undo git update-index --assume-unchanged <file> Why do I need to explicitly push a new branch? What is the meaning of git reset --hard origin/master? Git - How to close commit editor? Warning: push.default is unset; its implicit value is changing in Git 2.0 SVN Repository on Google Drive or DropBox Should composer.lock be committed to version control? How can I make git accept a self signed certificate? Git clone without .git directory How do I check out a specific version of a submodule using 'git submodule'? How can I revert multiple Git commits (already pushed) to a published repository? Delete all local git branches Show history of a file? How to update a pull request from forked repo? How to amend older Git commit? Adding a collaborator to my free GitHub account? View a file in a different Git branch without changing branches Git: How to rebase to a specific commit? Why does 'git commit' not save my changes? How do you make Git work with IntelliJ? Merge a Branch into Trunk What's a good (free) visual merge tool for Git? (on windows) How to unstage large number of files without deleting the content How do I rename a local Git branch? Rebasing remote branches in Git How can I delete all Git branches which have been merged? Git On Custom SSH Port Get changes from master into branch in Git How can I get a list of Git branches, ordered by most recent commit? git diff between cloned and original remote repository gitx How do I get my 'Detached HEAD' commits back into master What is a tracking branch? What does "Git push non-fast-forward updates were rejected" mean? Download single files from GitHub How to output git log with the first line only? How to tag an older commit in Git?

Questions with lockfile tag:

Waiting for another flutter command to release the startup lock Do I commit the package-lock.json file created by npm 5? What is the best way to ensure only one instance of a Bash script is running? Quick-and-dirty way to ensure only one instance of a shell script is running at a time