← Back to context

Comment by moritzwarhier

1 day ago

You are right that 'npm install' can upgrade versions even when a lock file is present, but AFAIK this should only happen it the lock file is not compatible with the package.json. I haven't seen it in a long time, and AFAIK it can't happen without you changing the package.json.

But yes, it's a reason to pin dependencies and use npm ci / yarn immutable etc.

Updates of transitive dependencies are afaik not automatically installed when there is a working lock file: this is the thing that changed some versions ago I think (I mixed up Node and npm versions in my initial comment).

So yes, to be sure that you never install anything else, it's best to use 'npm ci' or 'yarn install --immutable', which will fail if the lock file is broken or not present.

But 'npm install' does not install the latest patch release compatible with your package.json with precedence over the lockfile.

What it does do is upgrade if you edit the version range by hand to be incompatible with the lock file, e.g. increase major version of a package.

But if you have, say, Typescript ^5 in your package.json, but 5.4 in your lock file, 'npm install' won't upgrade it.

https://docs.npmjs.com/cli/v11/commands/npm-install

> 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, respecting the following order of precedence:

> npm-shrinkwrap.json

> package-lock.json

> yarn.lock

'npm ci' and friends are safer as they will always fail when they can't install from lock file without any conflicts or changes, that's correct.

Don't know how other package managers behave in this regard, except for yarn and pnpm.

PHP composer AFAIK behaves similar to npm?