DEV Community

Nikkhiel Seath
Nikkhiel Seath

Posted on • Edited on • Originally published at snikhill.tech

Symbols in package.json

Recently, I came across a dependency error. Basically, a package being used by a
project didn't have the correct version of a dependency listed as a peer.

{
    // package that had the issue
    "peerDependencies": {
        "package-a": "^6.5.7"
    }
}

{
    // project that used the said package
    "dependencies": {
        "package-a": "~6.6.7"
    }
}
Enter fullscreen mode Exit fullscreen mode

In this post I shall try to explain what symbols like ~ ^ and those numbers
mean?

Talking about the numbers first

I intially found it a bit weird that there are two decimals in this version
string. But, now, I know better.
Each of those digits represents a change in the version. Depending upon the
position of the digit that was incremented, the change can be divided into:

  • Major - A Breaking Change or a New feature
  • Minor - A change that maintains backwards compatiblity
  • Patch - A minor bug/error fix

Turns out that there is a whole set of rules defining what these digits are and
under what circumstances should and which digit be incremented. This rule set is
referred to as Semantic Versioning.
So, for a package with version string 8.5.4:

  • 8 => Major Version
  • 5 => Minor Version. Like: 5th revision of version 8
  • 4 => Patch Version. Like: 4th revision of the 5th revision (of version 8)

And now if a typo was fixed then, the digit representing "patch" would be
incremented making the new version string 8.5.(4 + 1) = 8.5.5.

In a proper production level released package, the minimum "major" is 1 and
minor, patch range from 0 to 9. (The first release is usually 1.0.0).

On the other hand, for a package that is released for development purposes,
usually has the "major" as 0 (and possibly no limit on range of major and
minor).

Talking about the symbols

Before I jump on symbols, I shall like to give a brief on what package.json
stores.

What exactly does package.json store?

A package.json file basically lists all the "pieces of code" (aka dependencies)
that the current project (which itself is a piece of code) may be dependent
upon.
Along with this, it stores what version of these "pieces of code" should
actually be used.

This version requirement can be:

  • strict: Only v1 of package-a
  • a little less strict: Either v2.3 or v3.1 of package-a
  • flexible: Anything after v3 of package-a will do fine.

How do symbols help?

Symbols like: ~, ^, <, || basically represents the above requirement in a
compact manner.

  • < aka less-than

    • Corresponds to major, minor, patch
    • <4.3.0 means any major or minor or patch update less than 4.3.0
    • 4.2.9 or 3.1.7 would work
  • > aka greater-than

    • Corresponds to major, minor, patch
    • >4.3.0 means any major or minor or patch update greater than 4.3.0
    • 5.1.6 would work but 4.2.9 won't

This is where it gets slightly tricky

The following symbols can allow updates to major, minor or patch depending upon which of them is defined.

~4.3.5 means a totally different thing than ~4
and ^7.8.6 is different from ^7.0.6.

  • ~ aka tilde

    • Allows patch update if a minor version is defined or a minor update if no patch version is defined
    • For ~4.3.5
    • Only patch updates would be allowed
    • Greater than or equal to 4.3.5 but, less than 4.4.0
    • ~4.3.6 would work but, ~4.4.1 won't work
    • For ~4
    • Only minor and patch updates would be allowed
    • Greater than or equal to 4.0.0 but, less than 5.0.0
    • 4.4.2 would work but, 5.0.0 won't work
  • ^ aka carret

    • Allows updates less than the left most non-zero digit
    • If major is zero and minor is a non-zero number then, only patch updates would be allowed
    • If major is non zero and minor is zero then both minor and patch updates would be allowed
    • For ^0.3.5
    • Greater than or equal to 0.3.5 but, less than 0.4.0
    • 0.3.6 or 0.3.9 would work but, 0.4.x won't work
    • For ^4.0.5
    • Greater than or equal to 4.0.5 but, less than 5.0.0
    • 4.1.5 would work but, 5.x.y won't work

Wrapping Up

This post obviously doesn't contain explanation for all the combantions possible
with all the relevant symbols. Instead, it is just an attempt to better explain
the concepts that confused me.

In a later post, I shall be sharing some actual examples using
node-semver, which is the tool that npm
uses
to parse these Semantic Versioning Complaint dependencies version.

Top comments (1)

Collapse
 
snikhill profile image
Nikkhiel Seath

Originally posted on my blog.

I can see that the indentation for lists vanished as I copied the article over to dev.to