How to use: npm tags
Tags: npm, javascript, typescript
Published: 2019-01-25 16:01:57

---
title: How to use: npm tags
published: false
description: The oldest npm feature you might not even have heard about.
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ekbs53ex2bi6uhv83531.jpg
tags: npm, javascript, typescript
published: true
---

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](https://docs.npmjs.com/cli/dist-tag)!


## 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
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 <piuccio@gmail.com>

```

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

### Consuming

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
```

### Publishing

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
```

or

```
$ 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](https://unsplash.com/photos/Ut9yic62qLE?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/search/photos/graffiti?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText). Shows spray tags, not npm tags.*