Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

`npm install blah` should install the latest version of `blah` that satisfies all of blah's `peerDependencies` #4055

balupton opened this Issue Oct 30, 2013 · 10 comments


None yet
7 participants

From my understanding on NPM at the current, peerDependencies only serves as a post-install complaint, that being:

  1. npm install blah installs the latest version, regardless of peerDependencies values
  2. the latest version of blah installed successfully
  3. npm then checks the peerDependencies of the latest version
  4. npm discovers that another dependency of the project doesn't statisfy blah's peerDependencies
  5. npm yells at you

What would be better, is if NPM only installed a version of blah that was compatible with the projects other dependencies. Making the workflow like:

  1. npm install blah will check if blah has peerDependencies defined, npm will use the current project's dependency versions to match against each published version of blah (going backwards) to try and find a version of blah which peerDependencies satisfy the project's dependencies, (or where peerDependencies is not defined, indicating compatible with all dependencies)
  2. If no compatible version is found, npm yells at you
  3. If a compatible version is found, the compatible version of blah is installed

In DocPad, we currently work around this by requiring all DocPad v6 compatible plugins to be of v2. So docpad install pluginName aliases to npm install -g docpad-install-pluginName@2 to ensure that we only install versions of the plugins that are compatible with DocPad v6. DocPad v5 compatible plugins used v1 instead.

This obviously isn't ideal, and will hopefully be deprecated by the suggestion here.

For the meantime, we are considering having a helper service that does exactly what we specified here. Then having our docpad install pluginName action perform the check itself. However, that is placing something in userland, that should probably be in NPM directly, as it would be beneficial for anyone using peerDependencies

@balupton balupton referenced this issue in docpad/docpad Oct 30, 2013


Semver Plugins #691


domenic commented Oct 30, 2013

I (author of peerDependencies) agree, this would be ideal behavior. Perhaps with a warning, or at least info message, since I think most people expect npm install x to give them the latest x. But yes, it sounds like you're willing to sink some resources into this; if so, npm patch welcome.

Yeah, the DocPad community does need this. For myself to implement this, I personally, won't be able to make the time to be able to.

If someone else can, what bounty would be enough to get this implemented sooner rather than later?

Hrmmm, no takers it seems...

Any advice on implementing this? Where should I get started? What do I need to consider? etc?

I looked at this but haven't had the time to dedicate to it recently.

What I had in mind was a new flag along the lines of --latest-compatible. When that flag is set, then before actually installing the package, you just grab the http://registry.npmjs.org/bla JSON and loop through the list of versions until you find one that meets all of the existing peer dependencies, then do a regular install of that version.

The one down-side to this approach is that if the plugin author didn't bother to specify any peer dependency, it would just install the latest version. But I think that would be OK, and if you really wanted, you could still have DocPad check the package.json at start-up and refuse anything that doesn't have the appropriate peer dependency.

The code that checks peer dependencies is in https://github.com/isaacs/npm/blob/master/lib/install.js, althought it might be worth extracting it to a separate file at this point.

Oh, then if something fails a regular npm install due to peer dependencies, we should add a note about that flag to the error message.

balupton commented Jan 4, 2014

The one down-side to this approach is that if the plugin author didn't bother to specify any peer dependency, it would just install the latest version.

Fine by me. 👍

What I had in mind was a new flag along the lines of --latest-compatible.

Could we do without needing a flag? One could easily forget the flag and then install incompatible dependencies which I'm not sure would ever be desirable.

nfriedly commented Jan 6, 2014

My reasoning for the flag is that silently installing an older version of bla when you do npm install bla might end up surprising a lot of people.

I'd like the two-step process where you do npm install bla, it fails, then you do what the error message says and run npm install bla --latest-compatible, because then you know that you're on an older version of bla and you'd know why.

balupton commented Jan 6, 2014


joliss commented Feb 24, 2014

@balupton My understanding is that you want npm to be smart about which versions to install, rather than detecting a mismatches and erroring out, correct? I believe a proper solution to this basically amounts to writing a constraint solver. For instance, in Ruby Bundler that's resolver.rb. It probably also requires hooking into npm's own dependency resolution mechanism.

So this is very non-trivial to fix.


isaacs commented Apr 17, 2014

@joliss It's not THAT hard. After all, npm already does constraint solving in many places, and node-semver provides a nice concatenative DSL for specifying such constraints.

But it isn't trivial, for sure.

Unless we just remove peerDependencies entirely and let plugin ecosystems sort it out for themselves. That'd be trivial, for sure :) But also quite costly in other ways.

@lautis lautis referenced this issue in baconjs/bacon.model Jun 12, 2014


use peerDependencies for baconjs #2

@othiym23 othiym23 added this to the multi-stage install milestone Jul 24, 2014


iarna commented Dec 15, 2014

Current peerDependencies behavior will be deprecated soon (see #6565 and #6930)

@iarna iarna closed this Dec 15, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment