auto vs lerna vs release-it vs semantic-release vs semantic-release-monorepo vs standard-version
Automating Versioning and Releases in JavaScript Projects
autolernarelease-itsemantic-releasesemantic-release-monorepostandard-versionSimilar Packages:

Automating Versioning and Releases in JavaScript Projects

auto, lerna, release-it, semantic-release, semantic-release-monorepo, and standard-version are tools designed to automate the versioning, changelog generation, and publishing process for JavaScript packages. They reduce manual errors by linking version numbers to commit history or configuration rules. semantic-release and auto focus on fully automated pipelines based on commit messages. lerna specializes in managing multiple packages within a single repository. release-it offers a flexible, interactive CLI for custom workflows. standard-version is a legacy tool for generating changelogs and bumping versions based on conventional commits. semantic-release-monorepo extends semantic-release to handle monorepo structures.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
auto106,1252,39755.2 kB1605 months agoMIT
lerna036,0758.95 MB316a month agoMIT
release-it08,916324 kB482 days agoMIT
semantic-release023,560298 kB3873 months agoMIT
semantic-release-monorepo0-25.6 kB-2 years agoMIT
standard-version07,965136 kB311-ISC

Automating Versioning and Releases: A Technical Deep Dive

Releasing software should be predictable and safe. The tools auto, lerna, release-it, semantic-release, semantic-release-monorepo, and standard-version all aim to remove manual steps from versioning and publishing. However, they solve this problem in different ways. Some focus on strict automation, while others offer flexibility or monorepo support. Let's compare how they handle configuration, monorepos, and commit rules.

⚙️ Configuration Style: Files vs. CLI

How you define release rules varies significantly. Some tools use dedicated config files, while others rely on package.json or CLI flags.

auto uses a dedicated .autorc file (JSON or JS). It focuses on plugins to define behavior.

// .autorc
{
  "plugins": [
    "npm",
    "github"
  ],
  "labels": [
    { "name": "Major", "releaseType": "major" }
  ]
}

lerna uses lerna.json at the root of the repository. It defines versioning mode and package locations.

// lerna.json
{
  "version": "independent",
  "packages": ["packages/*"],
  "command": {
    "publish": { "conventionalCommits": true }
  }
}

release-it uses .release-it.json or .release-it.js. It allows detailed control over git, npm, and GitHub steps.

// .release-it.json
{
  "git": { "commit": true, "tag": true },
  "npm": { "publish": true },
  "github": { "release": true }
}

semantic-release uses .releaserc (JSON, JS, or YAML). It is strictly plugin-based and automated.

// .releaserc
{
  "branches": ["main"],
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/npm"
  ]
}

semantic-release-monorepo does not have its own config file. It is configured inside the semantic-release plugins array.

// .releaserc (with monorepo plugin)
{
  "plugins": [
    "semantic-release-monorepo",
    "@semantic-release/npm"
  ]
}

standard-version typically uses package.json or a .versionrc file. It is simpler but less flexible.

// package.json
{
  "scripts": {
    "release": "standard-version"
  },
  "standard-version": {
    "skip": { "tag": true }
  }
}

🗂️ Monorepo Support: Native vs. Plugin

Managing multiple packages in one repository requires special handling for versioning and publishing.

auto supports monorepos via plugins. It can detect independent packages and release them separately.

# auto detects monorepo structure via plugins
npx auto shipit

lerna is built for monorepos. It handles linking and versioning across packages natively.

# Lerna versions all packages or independent ones
npx lerna version --independent

release-it supports monorepos with workspaces configuration. You can define hooks for each package.

// .release-it.json
{
  "workspace": "packages/*",
  "hooks": {
    "after:bump": "npm run build"
  }
}

semantic-release requires plugins to handle monorepos. It does not support them out of the box.

// .releaserc
{
  "plugins": [
    "@semantic-release/commit-analyzer",
    "semantic-release-monorepo"
  ]
}

semantic-release-monorepo is the specific plugin that enables semantic-release to work in monorepos. It filters commits per package.

// Plugin usage in .releaserc
{
  "plugins": [
    "semantic-release-monorepo",
    "@semantic-release/github"
  ]
}

standard-version has poor monorepo support. It treats the repo as a single unit. You must script around it.

# Manual scripting required for each package
cd packages/a && npx standard-version
cd packages/b && npx standard-version

📝 Commit Message Enforcement: Strict vs. Flexible

Some tools require specific commit formats to determine version bumps. Others let you decide manually.

auto uses labels on Pull Requests or commit messages. It is flexible based on plugin setup.

# Git commit with label
git commit -m "Fix bug" --label "patch"

lerna can enforce Conventional Commits but allows manual version bumps too.

# Lerna with conventional commits
npx lerna version --conventional-commits

release-it does not enforce commit messages. You can bump versions manually or via prompts.

# Interactive prompt selects version
npx release-it

semantic-release strictly requires Conventional Commits. It decides the version based on commit types.

# Must follow convention
git commit -m "feat: add new login method"

semantic-release-monorepo inherits the strict Conventional Commit requirement from semantic-release.

# Must follow convention per package
git commit -m "feat(pkg-a): update api"

standard-version relies on Conventional Commits to generate changelogs and bump versions.

# Generates CHANGELOG.md based on commits
npx standard-version

⚠️ Maintenance & Deprecation Status

Tool longevity matters for long-term projects. Some tools are archived or shifting focus.

auto is actively maintained. It receives regular updates for new plugins and CI providers.

lerna is actively maintained. It remains the standard for JavaScript monorepos despite new competitors.

release-it is actively maintained. It adapts quickly to new registry and Git platform changes.

semantic-release is actively maintained. It is a cornerstone of modern CI/CD pipelines.

semantic-release-monorepo has limited maintenance. Consider multi-semantic-release for more robust monorepo support.

standard-version is archived. The repository is no longer updated. Do not use in new projects.

📊 Summary Table

PackageMonorepo NativeCommit EnforcementConfig FileStatus
auto✅ (Plugins)Flexible.autorcActive
lerna✅ (Built-in)Optionallerna.jsonActive
release-it✅ (Workspaces)None.release-it.jsonActive
semantic-release❌ (Needs Plugin)Strict.releasercActive
semantic-release-monorepo✅ (Plugin)Strict.releasercLimited
standard-version❌ (Manual)Strictpackage.jsonArchived

💡 Final Recommendation

Choosing the right tool depends on your repository structure and team habits.

For Monorepos: Start with lerna. It is built for this scenario and handles dependency linking well. If you prefer semantic-release automation, pair it with multi-semantic-release instead of semantic-release-monorepo for better support.

For Single Packages: Use semantic-release if your team follows Conventional Commits strictly. It removes human error from versioning. Use release-it if you want manual control or interactive prompts before publishing.

For Custom Workflows: Use auto. Its plugin system allows you to build a release process that fits unique requirements without writing a full script.

Avoid: standard-version. It is archived and lacks the automation features of modern tools. Migrate existing projects to semantic-release or release-it.

Final Thought: Automation reduces risk. Pick the tool that matches your commit discipline. If you cannot enforce commit messages, choose a tool that allows manual version bumps like release-it or lerna.

How to Choose: auto vs lerna vs release-it vs semantic-release vs semantic-release-monorepo vs standard-version

  • auto:

    Choose auto if you want a highly extensible automation tool that works well with both single packages and monorepos. It uses a plugin system to integrate with various platforms like GitHub, npm, and Slack. Ideal for teams that need custom release steps without writing a full pipeline from scratch.

  • lerna:

    Choose lerna if you are managing a monorepo with multiple independent packages that need coordinated versioning. It is the standard choice for linking dependencies and publishing multiple packages from a single repository. Best for large-scale projects where package interdependence is common.

  • release-it:

    Choose release-it if you prefer a configurable CLI that supports interactive prompts and custom scripts. It is suitable for projects that need flexibility in how releases are tagged, pushed, and announced. Great for teams that want control over each step of the release process.

  • semantic-release:

    Choose semantic-release if you want a fully automated, zero-configuration release process driven by commit messages. It enforces Conventional Commits and handles versioning, changelogs, and publishing without manual intervention. Best for teams committed to strict commit hygiene and CI/CD automation.

  • semantic-release-monorepo:

    Choose semantic-release-monorepo if you are already using semantic-release but need to support a monorepo structure. It acts as a plugin to enable independent releases for packages within a single repository. Use this only if you want to extend semantic-release rather than switching to a dedicated monorepo tool.

  • standard-version:

    Avoid standard-version for new projects as it is archived and no longer actively maintained. It was useful for generating changelogs and bumping versions based on conventional commits but lacks modern automation features. Migrate to semantic-release or release-it for better long-term support.

README for auto

auto CLI

auto is a tool designed to seamlessly automate the release workflow. It is powered by semantic version labels on pull requests. This approach does not require you to change your code or make any drastic changes to your current workflow.

While intended to run in a continuous integration (CI) environment, all auto commands can run locally as well.

Installation

auto is distributed through npm, but you can use it with a variety of package management platforms.

npm install auto

For auto installation in non-npm environments follow these instructions.

Getting Started

Getting started with auto is super easy.

Prerequisites

If your project is already published or has releases then you need to make sure that your last release is tagged and that it's the Latest Release on GitHub.

To tag your last release find the last commit where you bumped the version and run the following commands with your version number.

git tag v1.2.3
git push --tags

Then on GitHub go to your project's releases and click Draft a new release. In the Tag version field enter the version number you just tagged and click Publish release.

Setup Steps

  1. (OPTIONAL) Initialize all options and configure label text. If this is not run then auto will use the default configuration. This command will produce an .autorc. You can configure most flags and all labels/changelogTitles.

    auto init
    

    All options can also be configured via the .autorc file. As CLI options you supply them in snake-case (--foo-bar), but as .autorc options you supply them in camelCase (fooBar),

    Exclusive options (extends, labels) can only be set in the .autorc and do not exist as CLI flags.

    Any option in the .autorc will get overridden by the CLI flags if provided. The following are options that might be more useful to set in the .autorc than with a flag:

      baseBranch           Configure what your repo considers the base branch.
      plugins              Specify your plugins to load
      githubApi            If you are using enterprise github, `auto` lets you configure the github API URL that it uses.
      githubGraphqlApi     If you are using enterprise github and your company hosts the graphql at some other URL than the
                           `githubApi`, you can use `githubGraphqlApi` to set the base path for `auto`. The `githubGraphqlApi` gets
                           merged with `/graphql` to build the final URL.
    
  2. Configure environment variables

    You must configure some environment variables for publishing and releasing to work properly.

    • GH_TOKEN - Used for updating the changelog and publishing the GitHub release
    • NPM_TOKEN - Used to publish to npm. (only with NPM plugin)

    Local .env:

    You can also store these values in a local file at the root of your project named .env. Make sure to add this file to your .gitignore so you don't commit any keys! These environment variables will override any variable already set on the process. This enables you to have a per project configuration that isn't effected by your global setup.

    PROJECT_ROOT/.env:

    GH_TOKEN=YOUR_TOKEN
    NPM_TOKEN=PUBLISH_TOKEN
    
  3. Create your project's labels on github. If a label already exist, it will be updated.

    The types of labels that auto uses are:

    • Versioning Labels - used to calculate version numbers and make releases.
    • Changelog Labels - These labels do not effect the version calculation but they will change the section the PR displays in the changelog. These are customizable too, and you can even add your own sections. Read more here.

    To create the labels for your project on GitHub, run the following command with your GH_TOKEN.

    GH_TOKEN=YOUR_TOKEN auto create-labels
    # or with .env file
    auto create-labels
    
  4. Set up script

    auto is written so that each tool it exposes is useful in isolation. To version, changelog, publish and release your code all at the same time we've included the shipit tool. This tool takes the default auto workflow and puts it into one command.

    It will:

    • Publish canary releases when run from a PR or locally on any branch other than the baseBranch
    • Generate a changelog and publish a "latest" release to a package manager when run from the baseBranch
    {
      "scripts": {
        "release": "auto shipit"
      }
    }
    

    For detailed setup instructions,refer here

Usage (--help)

$ auto --help

auto

  Generate releases based on semantic version labels on pull requests, and
  other pull request automation tools.

Synopsis

  $ auto <command> <options>

Setup Command

  init            Interactive setup for minimum working configuration.
  info            Determine the environment and check if auto is set up correctly
  create-labels   Create your project's labels on github. If labels exist it will update them.

Pull Request Interaction Commands

  label       Get the labels for a pull request. Doesn't do much, but the return value lets you write you own
              scripts based off of the PR labels!
  comment     Comment on a pull request with a markdown message. Each comment has a context, and each context only
              has one comment.
  pr-check    Check that a pull request has a SemVer label
  pr-status   Set the status on a PR commit
  pr-body     Update the body of a PR with a message. Appends to PR and will not overwrite user content. Each
              comment has a context, and each context only has one comment.

Release Commands

  version     Get the semantic version bump for the given changes. Requires all PRs to have labels for the change
              type. If a PR does not have a label associated with it, it will default to `patch`.
  changelog   Prepend release notes to `CHANGELOG.md`, create one if it doesn't exist, and commit the changes.
  release     Auto-generate a github release
  shipit      Context aware publishing.

              1. call from base branch -> latest version released (LATEST)
              2. call from prerelease branch -> prerelease version released (NEXT)
              3. call from PR in CI -> canary version released (CANARY)
              4. call locally when not on base/prerelease branch -> canary version released (CANARY)
  latest      Run the full `auto` release pipeline. Force a release to latest and bypass `shipit` safeguards.
  canary      Make a canary release of the project. Useful on PRs. If ran locally, `canary` will release a canary
              version for your current git HEAD. This is ran automatically from "shipit".

              1. In PR: 1.2.3-canary.123.0 + add version to PR body
              2. Locally: 1.2.3-canary.1810cfd
  next        Make a release for your "prerelease" release line. This is ran automatically from "shipit".

              1. Creates a prerelease on package management platform
              2. Creates a "Pre Release" on GitHub releases page.

              Calling the `next` command from a prerelease branch will publish a prerelease, otherwise it will
              publish to the default prerelease branch.

Global Options

  -V, --version         Display auto's version
  -v, --verbose         Show some more logs. Pass -vv for very verbose logs.
  --repo string         The repo to set the status on. Defaults to looking in the package definition
                        for the platform
  --owner string        The owner of the GitHub repo. Defaults to reading from the package definition
                        for the platform
  --github-api string   GitHub API to use
  --plugins string[]    Plugins to load auto with. (defaults to just npm)
  -h, --help            Display the help output

Merging Quickly

One caveat of auto is that you need to be mindful of merging multiple PRs at once. You must not merge a PR while another is publishing (ex: lerna publish). While this window is small, it exists and you should know about it.

auto works by looking at the git tree to calculate the version bump then makes commits for the CHANGELOG.md and the new version. If you merge a PR while another is publishing:

  • they might try to publish the same version number
  • one will try to push over the other's changes and fail

The one exception to this rule with when merging a bunch of PRs with skip-release labels.

You still can't merge a PR that triggers a release and then merge a PR with skip-release. This will result in problem 3 from above. But you can merge a bunch of PRs with skip-release then merge a PR that triggers a release. Because skip-release is present no commits are made and the release is fine!

Enterprise

If you are using enterprise Github, auto lets you configure the Github API URL that it uses. You can configure this by using the CLI option --github-api, by setting the value in your .autorc, or during auto init.