6

In my JavaScript applications I may be declaring a few dozen dependencies in my package.json file.

It would take a while to go through each one of those dependencies and see which version they are on.

I just want to say: use the latest major version, but not the bleeding edge.

As an example, with a tool like Git I don't usually care about taking changes at the patch-level but if a new major release comes out I will want it.

Is there a similar concept when specifying the version of a npm module?

Jonathan.Brink
  • 23,757
  • 20
  • 73
  • 115
  • 1
    The "bleeding edge" is usually a bunch of bug fixes you probably want to have. – ceejayoz Mar 30 '16 at 00:12
  • @ceejayoz This is probably just my ignorance of the landscape, but how is that different than other tools like source control tools or browsers where I don't usually care (or want) things at the bleeding edge? – Jonathan.Brink Mar 30 '16 at 00:13
  • Another example is a module like `grunt`. I just want a stable version, not the bleeding edge which (I perceive) to not be as stable yet? – Jonathan.Brink Mar 30 '16 at 00:14
  • Already answered here: http://stackoverflow.com/questions/16073603/how-do-i-update-each-dependency-in-package-json-to-the-latest-version Note that this assumes the bleeding edge version is not the one listed on NPM. – Akshat Mahajan Mar 30 '16 at 00:20
  • @Jonathan.Brink NPM packages are *supposed* to use [SemVer](http://semver.org/) (plenty don't use it correctly, but that's the ideal). Under SemVer, versions are X.Y.Z, where X is major breaking changes, Y is new but backwards-compatible functionality, and Z is bugfixes. As such, if you're willing to be on 2.0.0, you're probably best being on 2.*.* as it'll include the latest bug fixes - *increasing* stability in general. The least stable version is going to be a brand new major version, IMO. – ceejayoz Mar 30 '16 at 00:30
  • @ceejayoz thanks...I'm starting to understand the philosophy now. So, does that mean that a recommended approach would be to always specify "*" since that's the latest? – Jonathan.Brink Mar 30 '16 at 13:29
  • @Jonathan.Brink `*` is not good, as a new major version (by definition) breaks things - you don't want your app going from 2.* to 3.* unexpectedly. If you do `npm install --save ` it'll use a version string along the lines of `^2.9.3`, which means "anything in the 2.* range that's 2.9.3 or higher". You'll get bugfixes and non-breaking feature updates, but no "oh shit, everything broke when they went to 3.0.0". – ceejayoz Mar 30 '16 at 13:33
  • @ceejayoz Gotcha, so basically, as a responsible consumer I need to at least be aware of which major version each of the modules I am using is at. I suppose this isn't as bad as it sounds because if I use `--save` when I first download the module it will insert the major version for me. If this is correct, please summarize your points in an answer so I can upvote! – Jonathan.Brink Mar 30 '16 at 14:04

2 Answers2

5

NPM packages (theoretically) use SemVer.

In SemVer, packages get a version number of X.Y.Z.

Z indicates bug fixes. Y indicates new features without changing existing ones. X indicates a major version that breaks backwards-compatibility.

Doing npm install --save <package> will result in a version string in your package.json like ^2.3.9, which means "anything in the 2.* range greater than or equal to 2.3.9". This'll mean you get bug fixes and non-breaking new features, but you won't unexpectedly be updated to a version 3.0.0 that breaks your application.

Note: I say "theoretically" because not everyone sticks to SemVer's ideal. You may find a 2.3.9 -> 2.3.10 upgrade that breaks stuff at times. Tests are handy here.

ceejayoz
  • 176,543
  • 40
  • 303
  • 368
2

Using npm i -S <pkg> should normally do the right thing.

A few caveats:

  • The above assumes if you are taking a runtime dependency on <pkg>. In installing a developer tool (like grunt) use -D or -G instead of -S.

  • Semantic versioning rule 9 says that publishers MAY identify pre-release versions using a suffix like -beta. Npm depends on it, so if package publisher FAILS to do it, you might take a dependency on a pre-release package without knowing it. Sophisticated npm publishers should know better, and sophisticated npm consumers should check the documentation.

  • A major version is '0' indicates the package is still in initial development, and the package SHOULD NOT be considered stable. (Semantic versioning rule 4.)

  • Consider using npm dist-tag ls <pkg> to see if there is some package-specific tag that identifies your intent better than latest. If so, use npm I -S <pkg>@<tag> to track that tag.

You can always use npm outdated to check if you dependend directly on a package with a new major release might want to consider upgrading to. It is by-design that major version upgrades do not happen automatically.

Burt_Harris
  • 6,415
  • 2
  • 29
  • 64
  • The `npm` package itself uses `dist-tag`s tags to good effect, to see this type **`npm dist-tag ls npm`**. If this doesn't work, upgrade to the `latest` (stable) build of npm by typing **`npm i -G npm`**. – Burt_Harris Jun 13 '16 at 19:44