Npm strikes back with v5

So anyone who installs NodeJs > 8 will most likely be upgrading to npm v5. (Let's face it most of us don't wait excitedly for its latest incarnation and explicitly upgrade to it).

In the last year npm's reputation really has taken a kicking from all directions. JavaScript enthusiasts will point to alternatives such as Yarn citing its faster performance and deterministic package installs, whilst most non-JavaScript centric development teams I've worked with will focus on the fact it can drastically slow down the build chain on their CI server.

Whilst this new release won't fix all the issues one might have, it does go a long way to fixing many of the perceived deficiencies with it.

Here are just a few of the recent improvements.

Speed

Firstly installs are just noticeably faster. In fact, the first time I used NVM to install I actually had to check what was going on the difference was so great (hence this article!).

Apparently, it can be up to 3 to 5 times faster. Whilst I have not tested this in any scientific manner the install time is certainly more "Yarn" like, which is another way of saying faster. Some of this performance comes from improvements made to the caching mechanism. Apparently retrieving packages from the cache was in some instances not much better than retrieving the same package over the network. This kind of defeats the purpose of storing something close by due to the assumption that you're going to need it often so it's obvious to see why this would improve performance.

The npm API endpoint has also been upgraded. Newer clients will benefit from a reduction in response size which again speeds up the install times.

Locking down those dependancies

By default an npm install will generate a lock file called package.lock.json. Entries in this file use a SHA 512 hash to match packages. Whilst npm shrinkwrap has been available for a while it was never the default. Without some kind of file to deterministically lockdown the dependency graph the default package.json entry of a dependency leaves one open to a semver range. Which means that you are reliant on the contributors of every package dependency to not release breaking changes when releasing non-major versions. Lets face it with the best will in the world there are always going to be instances where this or some other unforeseen circumstances cause issues.

Even if a developer manually changes every dependency in the package.json to use an explicit version, the packages themselves will most likely declare their dependencies using semver ranges.
This can be turned off though most project teams would want the deterministic behaviour that this provides. As an added bonus this can further improve install times as there is no check based on the range of the package version. The cache either has that version or it is downloaded from the registry.

Useful Feedback

The feedback screen has also been enhanced to be far more succinct. I would pretty much ignore the feedback on a successful install as there was always just too much info in previous versions and found the scrolling through the verbosity of the feedback in the terminal often more of a hindrance than an assistance on failed installs.

The above is the output from an install of the angular CLI which is a non-trivial package to install. Gone is the massive tree of dependencies that no-one probably ever read and in its place is a terse summary of the number of packages added. (An install of typescript yielded a total of 2 lines!).

Final thoughts

Npm 5 brings a lot of common sense improvements to the tool. Whilst I haven't experienced the 3 to 5 times improvement in speed that some people report (my very basic testing of an Angular CLI install resulted in 19.383s in v5 versus 34.562 in v4) this is still pretty impressive and I must admit after all the hype I have never found Yarn to be quite as fast as its own publicity promises (though is was a lot faster than older versions of npm).
I think that the lock file is a great addition that the majority of projects will benefit from. SemVer ranges are useful on an initial install as they stop massive duplication by allowing the download of a package once when it's version will satisfy multiple nodes in the dependency graph given the SemVer range expressed in their respective package.json files. However, after that they become a potential problem and now the default behavior of npm protects us from that.
All in all Node's default package manager just became faster, more helpful and more reliable everything a developer would want from a package manager.

Andrew de Rozario

Self / community educated developer who loves all things web, JavaScript and .Net related. Passionate about sharing knowledge, teaching and eating though maybe not in that order.

Subscribe to Just In Time Coder

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!