Search code examples
node.jsnpmyarnpkg

NPM and yarn.lock


Since NPM v7 the official docs state the following about npm install (emphasis mine):

This command installs a package and any packages that it depends on. If the package has a package-lock, or an npm shrinkwrap file, or a yarn lock file, the installation of dependencies will be driven by that

I was trying to find more information about npm install behavior with the yarn.lock present, but didn't find much. This blog post states:

With the new package-lock.json file we'll unlock the ability to do deterministically reproducible builds. It should now include everything npm needs to install the packages needed. Before npm 7 yarn.lock was ignored by npm, but this is no longer the case. It can now use it to keep itself up to date with the package tree.

GitHub blog:

In prior versions, the yarn.lock files were ignored, the npm CLI can now use yarn.lock as the source of package metadata and resolution guidance. If a yarn.lock file is present, then npm will also keep it up-to-date with the contents of the package tree.

But neither of them gives a clear picture of what actually happens when I run npm install with yarn.lock.

I'd like to get a grasp on it:

  • Can I run yarn locally to generate yarn.lock and reproduce the package tree on CI with npm install?
  • What exactly happens when I run npm install with yarn.lock? Does it get updated? Can it be run with (sort of) --frozen-lockfile? The npm ci command doesn't mention yarn.lock at all.
  • Does it support both v1 and berry?

Solution

  • Can I run yarn locally to generate yarn.lock and reproduce the package tree on CI with npm install?

    No, you still need a package-lock.json file if you want to reproduce the package tree using npm v7. v7 only uses the yarn.lock file as a source of package metadata and resolution guidance.

    This is because npm v7 generates the lockfiles with the a new lockFileVersion: 2 (backward compatible) to improve performance and allow reproducible builds with deterministic tree shape; it also tries to reduce reading from package.json file for metadata.

    What exactly happens when I run npm install with yarn.lock? Does it get updated? Can it be run with (sort of) --frozen-lockfile? The npm ci command doesn't mention yarn.lock at all.

    Yes, the yarn.lock file will be updated and npm will still create a package-lock.json file, and if a package-lock.json file is present, it’ll be used as the authoritative definition of the tree shape to create.

    As per this NPM blog post, the reason they don't support yarn.lock file yet is

    One common question we’ve gotten a few times now, once we announce that npm v7 will include support for yarn.lock files, is “Why keep package-lock.json at all, then? Why not just use yarn.lock only?”

    The simple answer is: because yarn.lock doesn’t fully address npm’s needs, and relying on it exclusively would limit our ability to produce optimal package installs or add features in the future.

    Finally,

    Does it support both v1 and berry?

    This is not clear, and is implied to change for berry as yarn uses a combination of yarn.lock file and yarn version to guarantee deterministic resolution.

    I suggest reading this blogpost along with the above post from npm for more in-depth explanation.