DEV Community

Cover image for How to use: npm tags
Andy Wermke
Andy Wermke

Posted on

How to use: npm tags

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!

What they are

Let's jump right into it:

  1. On every npm install <package> without an explicit version, a tag is used to resolve the right version number: The latest tag.

  2. On every npm publish a tag is either updated or created. Yes, it defaults to the latest tag, too.

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 latest tag!

Check this out:

$ npm show cowsay

cowsay@1.4.0 | MIT | deps: 4 | versions: 19
cowsay is a configurable talking cow

keywords: cow, cowsay, cowthink, figlet, talking, ASCII

bin: cowsay, cowthink


latest: 1.4.0

published a month ago by piuccio <>

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.

Using tags


To install a package, but not the latest tag:

$ 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.

Changing tags

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.

Difference to git tags

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.

Profit $$

So how can we use that feature to our benefit in day-to-day work?

We can:

  • 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.

Happy hacking!

Teaser photo by Paul Murphy on Unsplash. Shows spray tags, not npm tags.

Top comments (10)

philnash profile image
Phil Nash

Hi Andy,

Thanks for this article! This has helped me start to work on a new version of a module and share it easier with my colleagues in the other modules that require it. This was really clear and easy to read and understand.

andywer profile image
Andy Wermke

Thanks for the great feedback, Phil! That's very nice to hear :)

Btw, I remember you from Berlin.js JSConf Special 2017. Any good meetups or conferences in Berlin coming up that you would recommend?

philnash profile image
Phil Nash

Ooh wow, that was a little while back! πŸ˜…

I'm not around Europe myself right now, so my finger is not exactly on that pulse right now. I'd always recommend Berlin.js for meetups. If you're into Angular, then the NG DE conference is coming up in August. And, outside of Berlin but still highly recommended, Ruhr JS is happening in October.

kj800x profile image
Kevin Johnson

npm versions are analogous to git tags
npm tags are analogous to git branches

andywer profile image
Andy Wermke

Hey Kevin!
Git branches are a history of commits (= changes), but AFAIK no history is tracked anywhere for npm tags. The npm tag is only a stateless pointer without any history. Like a git tag ;)

kj800x profile image
Kevin Johnson

Haha yes I could have been more clear. I was just trying to be succinct on the train ride home. My point was that similar to git branches, npm tags are dynamic and moveable (latest and next will point to different versions as time varies, just like master would for git), whereas npm versions are fixed and unchanging, similar to how you would use git tags (e.g. v1.0.0).

stevewhitmore profile image
Steve Whitmore

Concise and easy to understand! I was facing a problem where I was burning through versions but had to publish before officially releasing. Using tags with timestamps in them made it possible to create unstable snapshots for testing. Thanks!

ankurk91 profile image
Ankur Kumar


jackzhoumine profile image

nice article. help well.

mauro_codes profile image
Mauro Garcia

Thanks for this Article! Was super useful!