Semantic versioning and npm

Caret(^) and Tilde(~) in package.json explained

Every time you install a package using npm in your project, the package name, and its version get appended under dependencies into the package.json file. Let’s have a closer look at the dependencies section.

In the example above, you can see that we have a format that is like package-name: "rule-symbol version-number". You are already familiar with the first part of this format, but what are the other two?

When someone publishes a package or updates an already existing package they provide a version number that follows semantic versioning spec.


Semantic versioning is also known as SemVer. It is a way to number software releases. The idea is to signal users of what has changed compared to the previous version. There are three parts in a version number.

The patch number is for bug fixes, security updates, or performance improvement. Things that are not visible to consumers. So, if the developer found a bug in the example above and they fix it and release a new version, it will be 1.4.3

Note: A developer can fix multiple bugs or security vulnerabilities for a single release. The version number is dependent on how many times the package was released and not on the number of bugs fixed.

An increase in minor number means that a new feature got added to the package without making any breaking changes. So, if a new feature gets added to the example above, it will be 1.5.0 The patch number is changed to zero because there have been no bugs found yet.

The major number gets increased when a developer makes changes, adds a new feature, or fixes some bugs that break the existing package. So, when major number increases, both minor and patch reset to zero. For the example above major version release will be 2.0.0

Rule symbol

Whenever you install a package without specifying the version, npm installs the latest available version of that package.

Story time: Now, let’s say if you were working on a project at your workplace and you came home and downloaded the project on your home machine from GitHub to work on it. You run the command npm install to install all the packages. But there was a new major release of one of the packages that you are using, and npm by default installed the latest version, and your whole app stopped working because the new version broke something that your app was relying on. You can end up spending hours trying to figure out what is wrong just because one package was updated. What if you have 20 packages installed?

Story continued: Someone can say that npm should only install the specified version of a package by looking at the dependencies section. That approach certainly works, but then you will not be able to make any updates to your packages. So, if there are new features added to a package without any breaking changes, you will not be able to use them in your project, and you will be stuck with the specific version of a package.

Thankfully these are not the cases; npm puts a ruling symbol before the version number, and that symbol controls which version to install each time you say npm install. By default, it is a caret character (^).

  • Caret (^): A caret character means to install/update a package with the latest minor or patch version. So, if there are any new features added or bug fixes in a new version, install it. It’s similar to saying express: 4.x.x
  • Tilde(~): A tilde character means that only install/update a package if there is a new patch version available. In short, only install a package if there were any bug fixes. It means install express: 4.17.x version.
  • No symbol: A version without a ruling symbol means to install the exact version no matter if there are new features available or any bug fixes. So, install express: 4.17.1 .

If you want to learn more, check out

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store