NB: I'm creating this issue in the yarn repo, but this is actually a shared issue between yarn and npm.
With the release of npm 5 back in May, the Node ecosystem now has two lockfile-based package managers. This was overall a win for users, and it has been good to see competition in this space.
However now that there are two competing lockfile formats this can create a new problem for users, especially beginning developers.
When npm 5 came out, Heroku added a new failure if an application was submitted with both npm and yarn lockfiles. In the past few months this has become the most common reason Node builds fail on Heroku and these failures account for ~10-12% of all Node build failures on the platform. Thousands of developers hit this every month.
It's surprisingly easy to end up with both in your repository. Even as an experienced developer I've found myself running the wrong tool for a specific project and having to catch myself before commiting. For an inexperienced developer building their first server / react / angular project who might not understand what a package manager, lockfile, or git repo is, this can be highly confusing.
Neither tool will give a warning or error if the other lockfile exists:
❯ ls *lock*
ls: *lock*: No such file or directory
❯ npm --version
5.8.0
❯ yarn --version
1.5.1
❯ npm install
npm notice created a lockfile as package-lock.json. You should commit this file.
added 659 packages from 437 contributors in 10.553s
❯ yarn install
yarn install v1.5.1
info No lockfile found.
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 📃 Building fresh packages...
success Saved lockfile.
✨ Done in 7.67s.
❯ ls *lock*
package-lock.json yarn.lock
This is likely especially true for Yarn users where most of the documentation on the web instructs users to npm install
. Users who copy + paste commands from docs or Stack Overflow are likely to end up here.
I've spoken to @zkat and @iarna at npm and @arcanis on yarn, and all agreed that this is an issue that should be addressed, but there was not full agreement on how. Ideally this issue prompts discussion and both tools can agree on how we can help users here.
I've compiled a list of potential mitigations that have been suggested to me:
Potential solutions
Do nothing
Is there a technical reason a user might want two lockfiles? In this case, how can external tools determine which package manager should be used for that application?
Error if the other lockfile exists
Yarn could print an error and exit if package-lock.json
exists and vice-versa.
Pros:
- simple and easy to implement
- the user gets an error where they are in a position to immediately fix it
Cons:
- Not a fantastic user experience
Convert the other lockfile
Yarn could read package-lock.json
, convert it into yarn.lock
, and remove package-lock.json
. npm could do the opposite.
Pros:
- great user experience
- users switching tools would not get a new set of dependencies as a side-effect
Cons:
- My understanding is that due to the different dependency resolution strategies this conversion would be lossy both ways
- Requires each tool to add and maintain code to understand the other lockfile
- Lockfile formats may change over time
Delete the other's lockfile
Just remove the other lockfile and create a new one
Pros:
- effectively prevents this situation
Cons:
- surprising behavior
- user gets new set of dependencies
Run the other tool for the user
If yarn sees a package-lock.json
but not a yarn.lock
it could log a warning and call npm install
for the user
Pros:
- User gets what they wanted
Cons:
- Surprising behavior
- somewhat complicated
Add config to package.json
to indicate
Add a field in package.json
to indicate which package manager a project should use
"package-manager": "yarn"
Pros:
- Explicitly conveys the user's intent
Cons:
- Adds more config for the user
Other?
Maybe I'm missing something that would work better
cat-compatibility triaged needs-discussion