Hassle-free NPM package publishing with release-it

3 min read

I’ve just created my first NPM package and was searching the web for ways to automate the publishing step.

I had the following requirements in mind:

  • A single command from start to end.
  • Every release should follow semver with automatic creation of git tags.
  • Simple way to choose the type of release. (major / minor / patch)
  • Auto generation of release notes based on commit history.
  • Possibility to draft a release on GitHub. (nice to have)
Semantic Versioning

A git tag with semver (credit: baeldung)

As I was searching for tools to accomplish the above, I came across release-it, which satisfied all of my requirements with the right amount of flexibility.


Here is a short demo of me publishing a package using release-it:

Publishing my package to NPM

A GitHub release is created with the draft status containing a prefilled changelog and uploaded assets without any manual intervention.

GitHub draft release

A GitHub draft release with the changelog prefilled

The whole process only took under a minute with release-it. Usually, we have to type in various commands in sequence for bumping the version, generating a git tag, creating a tarball, writing a changelog, and finally publishing the package to NPM.

All of these steps are automated by release-it, and every aspect of it is customizable with a configuration file.


npm install -D release-it

After installation, add release-it to the scripts section in your package.json file.

  "name": "my-package",
  "version": "0.0.0",
  "scripts": {
    "release": "release-it"

Now create a .release-it.js file in your project’s root directory. We will use this to configure it.


Once your package is ready to be published, run the following command in the terminal:

npm run release

You will be shown the changelog first and then followed by a series of prompts with the option to choose the type of release (major / minor / patch).

Here is the configuration I used to publish the package as shown in the demo:

module.exports = {
  git: {
    commitMessage: 'chore: Release v${version}',
    tagName: 'v${version}',
    requireCommits: true, // require commits since last tag
    requireCleanWorkingDir: true, // exits if local not upto date with remote or if workdir is unclean
  github: {
    release: true, // creates a github release
    draft: true, // github releases are only drafted, confirm the draft in github releases page to publish it
    releaseName: 'v${version}',
    commitArgs: ['-S'], // creates gpg signed commits
    tagArgs: ['-s'], // creates gpg signed tags
    assets: ['tar/*.tgz'], // assets to be included in the GitHub releases page
  npm: {
    publish: true,
  hooks: {
    // runs lint before publishing
    'before:init': ['pnpm lint'],
    // build the package to publish and the generate a tarball for use in github releases
    'after:bump': 'pnpm build && pnpm tarball',
    'after:release': 'echo Successfully created a release v${version} for ${repo.repository}.',

The added support for lifecycle hooks is my favourite feature since it allows us to run tasks at various stages of publishing. Using these hooks, we could run our lint and test jobs before we begin the release process saving us time if they were to fail later.

Refer to its documentation to learn more about the configuration.


I loved the intuitive prompt-based approach offered by release-it as it helps reduce the friction involved in package publishing.

You can also check out my package as a reference in setting it up.

I hope this post motivated you to streamline your package release process!