There is a feature in npm that affects every
npm install, every
npm publish, yet most npm users seem to be unaware of.
Time to talk about npm tags!
Let's jump right into it:
npm install <package>without an explicit version, a tag is used to resolve the right version number: The
npm publisha tag is either updated or created. Yes, it defaults to the
So let's assume a busy work day has just begun and you add a new package to your dependencies:
$ npm install cowsay
Now as you did not specify any version to install, how does npm decide which version to use? It uses the
Check this out:
$ npm show cowsay email@example.com | MIT | deps: 4 | versions: 19 cowsay is a configurable talking cow https://github.com/piuccio/cowsay keywords: cow, cowsay, cowthink, figlet, talking, ASCII bin: cowsay, cowthink (...) dist-tags: latest: 1.4.0 published a month ago by piuccio <firstname.lastname@example.org>
Have a look at
dist-tags. It shows only one tag, the
latest tag. Judging by
npm show's output we can already imagine what a tag's function is:
Tags are a mapping from some human-friendly identifier to a specific version number.
Aha! So when you do your casual
npm install cowsay, npm will fetch the package metadata (try
npm show cowsay --json), including a list of all published tags of the package. The
latest tag will tell npm what version to install.
So why doesn't npm just install the version with the most recent publishing timestamp? We will get to this in no time, but let's add a spoiler here:
Because the most recent
npm publish might not have published a stable version, but maybe some early beta version that the user is not supposed to run in production.
To install a package, but not the
$ npm install <package>@<tag>
A popular example would be:
# Install the latest alpha version of React $ npm install react@next
To publish a version of your precious package that should not be installed by default:
$ npm publish --tag <tag>
This way you can easily share some unstable code with others, so they can test it:
$ npm publish --tag beta
$ npm publish --tag testing-feature-new-dashboard
As already mentioned before, running
npm publish without a
--tag parameter will also update a tag: The
latest tag which is the default tag for publishing and installing.
You can always change tags to point to another version if you need to. Use the
npm dist-tag sub-command for that:
$ npm dist-tag --help npm dist-tag add <pkg>@<version> [<tag>] npm dist-tag rm <pkg> <tag> npm dist-tag ls [<pkg>] alias: dist-tags
Use it to fix the tag if you accidentally published a version using the wrong tag.
It's important to note that npm tags are semantically different to how git tags are commonly used, even though technically they are very similar.
A git tag points to a commit, which is the code at a particular point in time, and usually never changes. The git tag is essentially the equivalent of an npm version.
An npm tag on the other hand is a mutable pointer to a version, which in turn is an immutable pointer to the code at one particular point in time. So an npm tag is basically a meta pointer.
When thinking in git terms, both npm tags and npm versions could be implemented using git tags, just that the former type of tag would be considered mutable, while the version git tags would be considered immutable.
So how can we use that feature to our benefit in day-to-day work?
Share an unstable version with beta testers:
npm publish --tag beta
Publish a use-once-and-forget version:
npm publish --tag testing-new-feature
Installing that version on the other end will be just as simple:
$ npm install my-fancy-package@testing-new-feature
Release early, release often. Don't screw with your production users, though. Use npm tags.