rivet

Pre-releases

Manage alpha, beta, and rc releases with rivet

rivet has built-in support for pre-release versions (alpha, beta, rc, or any tag you define). Pre-release versions are useful for testing changes before a stable release.

How it works

When a package is in pre-release mode, rivet bump produces versions like 1.2.4-beta.1 instead of 1.2.4. The pre-release tag is also used as the npm dist-tag during rivet release.

Configuration

You can configure pre-release mode in two ways:

Via config file

Add preMode entries to your .rivet/config.json:

{
  "preMode": [
    {
      "tag": "beta",
      "packages": ["@scope/experimental-*"]
    },
    {
      "tag": "alpha",
      "packages": ["@scope/early-access-*"]
    }
  ]
}

Each entry specifies a tag and the packages it applies to. Package names support glob patterns and ! negation:

{
  "preMode": [
    {
      "tag": "rc",
      "packages": ["@scope/*", "!@scope/stable-core"]
    }
  ]
}

A package can only belong to one pre-mode entry at a time.

Via CLI

Use the pre command for interactive management:

# Interactive: select packages and enter a tag
rivet pre

# Enter pre-release mode
rivet pre enter beta --package @scope/pkg-c
rivet pre enter beta --package @scope/pkg-c --package @scope/pkg-d
rivet pre enter beta --package "@scope/pre-*"

# Migrate from one tag to another
rivet pre enter rc --package @scope/pkg-c --force

# Exit pre-release mode
rivet pre exit --package @scope/pkg-c
rivet pre exit --package "@scope/pre-*"

# Show current status
rivet pre status

Package name resolution supports:

  • Exact names: @scope/pkg-c
  • Partial names: pkg-c resolves to @scope/pkg-c by suffix matching
  • Globs: "@scope/pre-*"
  • Negation: "!@scope/special" (in config only)

Version behavior

When rivet bump runs, pre-release versions are computed as follows:

Current versionBumpResult
1.2.3patch1.2.4-beta.1
1.2.3minor1.3.0-beta.1
1.2.3major2.0.0-beta.1
1.2.4-beta.1patch1.2.4-beta.2
1.2.4-beta.5minor1.2.4-beta.6

Key behaviors:

  • First pre-release bump: The base version is bumped first (e.g., 1.2.31.2.4), then the tag is appended with counter 1.
  • Subsequent bumps: Only the pre-release counter increments. The base version stays the same.
  • Tag migration: Moving from beta to rc resets the counter to 1 (1.2.4-rc.1).
  • Exit pre-release mode: The version drops the tag entirely (1.2.4-beta.31.2.4).

State file

Pre-release state is stored in .rivet/pre.json:

{
  "@scope/pkg-c": { "tag": "beta", "count": 3 },
  "@scope/pkg-d": { "tag": "alpha", "count": 1 }
}

This file is managed automatically during rivet bump.

Atomic counters

The pre-release counter is only saved after all file writes succeed. If rivet bump fails partway through, the counter does not increment. This means a retry produces the same pre-release version — no wasted pre-release numbers.

Publishing

Pre-release versions are published with the appropriate npm dist-tag:

# Automatically uses the pre-release tag (e.g., --tag beta)
rivet release

# Override the dist-tag
rivet release --tag next

If a package has a pre-release version like 2.0.0-rc.1, rivet publishes with --tag rc automatically.

Mixed pre-release and stable

A single rivet bump can handle both pre-release and stable packages:

  • Pre-release packages get their tagged versions
  • Stable packages get normal versions
  • Changelogs are generated for both, but pre-release entries are consumed without generating duplicate entries on the next cycle

On this page