We're live-coding on Twitch! Join us!
Node and Npm Version Numbering: Guide and Best Practices

Node and Npm Version Numbering: Guide and Best Practices

When creating a new Node project, one of the very first things you'll do is select your dependencies and devDependencies for your project. When declaring Node dependency version numbers, there are many different ways to specify the version number you want. That's because Node uses semantic versioning when declaring modules.

Let's say we're bringing expressJS into our project. You can declare that dependency version many ways. Here are a few examples.
  • 4.8.5
  • >4.8.5
  • >=4.8.5
  • ~4.8.5
You may have read through some tutorials where they will declare dependencies with some characters and a version number and wonder what exactly does that mean?
  "name": "awesome-sauce",
  "main": "server.js",
  "dependencies": {
    "express": "^4.0.x" <-- what in the world is that?!
Let's look through the various ways we can declare version numbers in our Node package.json files.

A Specific Version

v2.0.0 or =2.0.0 The v and the = will be removed and the exact version 2.0.0 will be used.

Version Ranges

There are a lot of ways to define a version range. Why would we need to define a version range? There are many reasons why you would want version ranges. When modules and dependencies that you use are updated, you want to make sure that they don't break your project. This is why it's good to not specify latest as your version. For example, when ExpressJS was updated from version 3 to version 4, many applications would have broken. It would have been good to specify that you only wanted the latest of version 3, but not anything from version 4. Here's a handy table of the ways we can define version ranges:
Version Number Explanation
latest Takes the latest version possible. Not the safest thing to use.
*, x Wildcards. Can be any version at all. Crazy stuff.
4, 4.*, 4.x, ~4, ^4 Any version that starts with 4. Takes the latest.
>4.8.5 Choose any version greater than a specific version. Could break your application.
<4.8.5 Choose any version lower than a specific version.
>=4.8.5 Anything greater than or equal to a specific version.
<=4.8.5 Anything less than or equal to.
4.8.3 - 4.8.5 Anything within a range of versions. The equivalent of >=4.8.3 and <=4.8.5
~4.8.5 Any version "reasonably close to 4.8.5". This will call use all versions up to, but less than 4.9.0
~4.8 Any version that starts with 4.8
^4.8.5 Any version "compatible with 4.8.5". This will call versions up to the next major version like 5.0.0. Could break your application if there are major differences in the next major version.
~1.2 Any version compatible with 1.2

Best Practices

Personally, when calling dependencies for my project, I will use the tilde ( ~). By specifying your express dependency using ~4.8.5, you will be able to get bug fixes when new smaller versions come around, but you won't grab versions that break your project. You are never going to be sure what updates come with the new versions and if those updates will break your application. For express, we definitely won't want to grab version 5 in the future. Even 4.9.0 could break our application so the tilde will keep us safe since it won't let our application grab that version. TLDR; Use the tilde so you don't break your applications, but still get the latest bug fixes.


Hopefully this clarifies what all those crazy symbols and version numbering schemes mean. Semantic versioning can be seen in more than just npm modules. You can see it used in Grunt and also Bower versions as well.

Like this article? Follow @chris__sev on Twitter