Blog Publish an npm package with automated releases

Publish an npm package with automated releases

2 min read

Publish an npm package with automated releases
TL;DR Structure your commits with a convention, then let CI decide the version, generate the changelog, and publish to npm on merge. Releasing becomes a push to main, and the version and changelog are derived from the work instead of maintained by hand.

Publishing an npm package by hand is a small ceremony that goes wrong at the worst times: you bump the version but forget the changelog, or tag before publishing, or publish the wrong build. Automating it turns releasing into a push. Here is the shape of it.

The idea

Instead of maintaining the version and changelog by hand, you derive them from your commits. You adopt a commit convention that labels each change by type, and CI reads those labels to decide the next version, generate the changelog, tag, and publish, all on merge to your release branch.

The commits become the source of truth. The release is a consequence of the work, not a separate manual task.

Structure your commits

Adopt a convention where each commit is prefixed by its type:

fix: correct off-by-one in pagination
feat: add retry option to the client
feat!: drop support for the old config format

A fix is a patch, a feat is a minor, and a breaking change (the !) is a major. Now the version is not a decision someone makes at release time; it is implied by what changed.

Let CI do the release

On merge to your release branch, a CI job runs the release tooling:

  • It reads the commits since the last release.
  • It computes the next version from their types.
  • It generates changelog entries from them.
  • It tags the release and publishes to npm.

You store an npm token as a CI secret so the publish step can authenticate. From then on, merging is releasing.

What you keep, what you hand off

The key thing this does not do is take away your judgement. You still decide what merges to the release branch, which is to say you still decide when a release happens and what is in it. What you hand off is the mechanical part: the bump, the changelog, the tag, the publish, in the right order, every time.

Why it is worth it

A manual release process is fine until the day you are tired or rushed, which is exactly when the mistakes happen and a broken version reaches your users. Deriving the release from the commits removes that whole class of error. Releasing well should be boring and repeatable, and this is how you make it so.

FAQ

Why automate npm releases?

Manual releasing is a checklist you eventually get wrong: bump the version, update the changelog, tag, publish, in the right order. Automation derives all of that from your commits, so a release is reliable and repeatable instead of a careful ritual.

How does the version get decided automatically?

With a commit convention. Commits are labelled by type, and the tooling reads them to decide whether the change is a patch, a minor, or a breaking major, then bumps the version accordingly. The commits become the source of truth for the version.

Do I still control what gets published?

Yes. You control what merges to your release branch, and that is what triggers a release. The automation handles the mechanical steps once you decide the code is ready, so you keep the judgement and hand off the tedium.