For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt, and this page is available as Markdown at /guide/advanced/release-management.md.
close
  • English
  • Release management

    This chapter introduces npm package version management and release practices for Rslib projects.

    Configure package.json

    Before publishing an npm package, first complete its basic package.json configuration. This includes confirming the package name and initial version, and configuring its exports, runtime requirements, and publishing scope. For example, an ESM package built with Rslib can use the following configuration:

    package.json
    {
      "name": "@example/lib",
      "version": "0.0.0",
      "type": "module",
      "exports": {
        ".": {
          "types": "./dist/index.d.ts",
          "default": "./dist/index.js"
        }
      },
      "types": "./dist/index.d.ts",
      "files": ["dist"],
      "engines": {
        "node": ">=22.19.0"
      },
      "publishConfig": {
        "access": "public",
        "registry": "https://registry.npmjs.org/"
      }
    }

    Pay particular attention to the following fields:

    FieldDescription
    exports, typesPoint the exports and type declarations to the actual build artifacts generated by Rslib.
    filesExplicitly list the files to publish to avoid accidentally publishing tests, configuration, and other unrelated content.
    engines.nodeDeclare the minimum supported Node.js version.
    publishConfigScoped packages can set access: "public" for public publishing. This field can also override the registry used when publishing.
    dependencies, optionalDependencies, peerDependencies, devDependenciesRslib applies default external rules to third-party dependencies based on these fields. Declare dependencies according to their actual purpose; see Default handling of third-party dependencies for details.
    sideEffectsDeclare package side effects correctly, including files that have import side effects such as CSS, polyfills, and global registrations.

    Also make sure that the package does not set private: true. It is also recommended to add description, license, and repository so users can understand and locate the project on npm.

    pnpm version management

    pnpm provides versioning and publishing features for recording changes, updating package versions, generating changelogs, synchronizing dependency versions between workspace packages, and publishing npm packages.

    pnpm version requirement

    These versioning features require pnpm v11.13.0 or later. We recommend pinning the pnpm version with packageManager and declaring the minimum version with engines.pnpm:

    package.json
    {
      "packageManager": "[email protected]",
      "engines": {
        "pnpm": ">=11.13.0"
      }
    }

    The common versioning and publishing commands can be run locally or integrated into GitHub Actions and other CI platforms:

    CommandStagePurpose
    pnpm changeDevelopmentRecord affected packages, version bump levels, and changes.
    pnpm change statusPreparationView pending change records and their version changes.
    pnpm versionPreparationUpdate package versions, including multiple workspace packages with -r.
    pnpm lanePreparationManage prerelease channels such as Alpha, Beta, and RC.
    pnpm publishPublishingPublish packages directly to npm.
    pnpm stage publishPublishingStage packages on npm for review and approval before release.

    You can configure pnpm versioning behavior in pnpm-workspace.yaml. For example, configure a fixed version group to keep multiple packages at the same version:

    pnpm-workspace.yaml
    versioning:
      fixed:
        - ['@example/*']

    See the pnpm versioning configuration for all available options.

    Release workflow

    A complete pnpm-based release process includes the following steps:

    1. Record changes
    2. Update versions
    3. Maintain changelog
    4. Build and validate
    5. Publish to npm

    Record changes

    After completing changes that need to be released, run pnpm change to record the affected packages, version bump level, and change summary:

    pnpm change

    pnpm generates a change record in the .changeset/ directory based on the interactive options. The summary is used to generate the changelog during release, so it should clearly describe the user-facing behavior change. Commit the generated change record file together with the code.

    You can also record changes non-interactively by specifying the package name and options such as --bump and --summary:

    pnpm change --bump patch --summary "Example change" @example/core

    Before preparing a release, view pending change records and their corresponding version changes:

    pnpm change status

    Single-package repositories can skip this step when change intents are not needed and specify the version type directly when updating versions.

    Update versions

    Run pnpm version to update versions when preparing a release:

    # Single-package repository
    pnpm version patch
    
    # monorepo
    pnpm version -r

    When run in a Git repository, regular pnpm version creates a Git commit and an annotated tag for the version change. A single-package repository can inspect the generated commit and tag, then push them to the main branch for publishing.

    If you want to wrap single-package version updates in a script, add the following to package.json:

    package.json
    {
      "scripts": {
        "bump": "pnpm version -m \"release: v%s\""
      }
    }

    In a monorepo project, run pnpm version -r. Recursive mode applies the change records and updates package versions, workspace dependencies, and changelogs, but does not create a commit or tag because one run may produce different versions for multiple packages. After checking the generated files, commit and push these changes to an agreed release branch, such as release/v1.2.3, and create a PR. Publish from that branch first, then merge the PR after the release is verified.

    During the version update process, choose an appropriate version type based on your needs.

    Stable and prerelease versions

    Stable versions are intended for all users. They do not include a prerelease identifier and normally use the latest dist-tag.

    Alpha, Beta, and RC versions are installable test versions released before a stable version. Use an npm dist-tag that matches the version suffix so that prereleases do not affect the default installation:

    Versionnpm dist-tag
    1.0.0-alpha.0alpha
    1.0.0-beta.0beta
    1.0.0-rc.0rc
    1.0.0latest

    You can create a prerelease with pnpm version:

    pnpm version prerelease --preid beta

    If a group of workspace packages needs continuous prerelease releases, use pnpm lane to maintain an independent prerelease channel:

    pnpm lane beta --filter '@example/*'
    pnpm version -r
    
    # Move back to the main lane before releasing a stable version
    pnpm lane main --filter '@example/*'
    pnpm version -r
    Note

    Do not publish prereleases to latest, otherwise users installing the package normally may receive an unstable version.

    Snapshot packages

    Snapshot packages help validate a PR, branch, or commit without changing the stable version or changelog. For local validation, build and pack the package, then install the generated archive in a consumer project:

    # Run in the library project
    pnpm build
    pnpm pack
    
    # Run in the consumer project
    pnpm add /path/to/package.tgz

    To provide collaborators with an installable Snapshot package in a PR, use pkg-pr-new. It publishes packages to a separate npm-compatible service rather than the npm registry, so it does not increase the number of npm package versions or modify package metadata such as dist-tags.

    Maintain changelog

    When you run pnpm version -r, pnpm generates changelogs from the summaries recorded by pnpm change. To maintain a CHANGELOG.md for each package in the repository, set versioning.changelog.storage to repository:

    pnpm-workspace.yaml
    versioning:
      changelog:
        storage: repository

    If the project uses GitHub release notes as the user-facing version record, you do not need to maintain an additional CHANGELOG.md in the repository. GitHub supports automatically generated release notes, and you can add release highlights, migration instructions, and important notes to the generated content.

    Build and validate

    After determining the version to publish, use the corresponding commit locally or in CI, install dependencies, and build:

    pnpm install --frozen-lockfile
    pnpm build

    Before publishing, run pnpm publish --dry-run to check the files and package information that will be published:

    # Single-package repository
    pnpm publish --dry-run
    
    # monorepo
    pnpm --filter './packages/*' -r publish --dry-run

    You can also check the package structure, exports, and type declarations to ensure that the final npm package can be resolved and installed correctly. Rslib supports the following Rsbuild plugins for these checks:

    Install the plugins first, then add them to the plugins configuration. The plugins check release artifacts after the build completes.

    npm
    yarn
    pnpm
    bun
    deno
    npm add rsbuild-plugin-publint rsbuild-plugin-arethetypeswrong -D

    The following configuration enables the checks with the CI environment variable set by most CI platforms, avoiding an impact on local build workflows. The checks run automatically when packages are built during the release workflow:

    rslib.config.ts
    import { defineConfig } from '@rslib/core';
    import { pluginAreTheTypesWrong } from 'rsbuild-plugin-arethetypeswrong';
    import { pluginPublint } from 'rsbuild-plugin-publint';
    
    export default defineConfig({
      dts: true,
      plugins: [
        pluginPublint({
          enable: Boolean(process.env.CI),
        }),
        pluginAreTheTypesWrong({
          enable: Boolean(process.env.CI),
        }),
      ],
    });

    You can also add syntax compatibility, bundle size, or installation tests based on the type of artifact.

    Publish to npm

    There are two ways to publish npm packages:

    • Staged publishing (recommended): pnpm stage publish separates uploading a package from making it publicly available. Staged versions are not resolved or installed by package managers, so maintainers can inspect the package before approving it on the npm website or with pnpm stage approve. This approach can reduce supply-chain risks if an npm token is stolen or a CI environment is compromised.

      # Single-package repository
      pnpm stage publish --tag latest --no-git-checks
      
      # monorepo
      pnpm --filter './packages/*' -r stage publish --tag latest --no-git-checks

      Approve the staged packages on the npm website after checking them.

    • Direct publishing: If manual approval is not required, use pnpm publish directly:

      # Single-package repository
      pnpm publish --tag latest --no-git-checks
      
      # monorepo
      pnpm --filter './packages/*' -r publish --tag latest --no-git-checks

    For prereleases, replace latest with the corresponding alpha, beta, or rc dist-tag.

    GitHub integration

    You can use GitHub Actions to build and publish the npm package. We recommend using npm Trusted publishing for OIDC authentication to avoid storing long-lived npm tokens in CI.

    Publish from a tag

    For a simple single-package repository, after updating the version, push the commit containing the version change to the main branch, then push the corresponding Git tag. The release workflow runs for the v* tag and can also be triggered manually:

    .github/workflows/release.yml
    name: Release
    
    on:
      push:
        tags:
          - 'v*'
    
      workflow_dispatch:
    
    permissions: {}
    
    jobs:
      publish:
        runs-on: ubuntu-latest
        environment: npm
        permissions:
          contents: read
          id-token: write
        steps:
          - name: Checkout
            uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
    
          - name: Setup Node.js
            uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
            with:
              node-version: 24
    
          - name: Install pnpm
            uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
            with:
              run_install: true
    
          - name: Build
            run: pnpm run build
    
          - name: Publish to npm
            run: pnpm stage publish --tag latest --no-git-checks
    Note

    To publish an alpha, beta, or other prerelease version, replace latest with the corresponding npm dist-tag.

    Publish from a release branch

    For a monorepo that publishes multiple packages together, use the release workflow to select an agreed release branch. After you use Run workflow to select the branch and npm dist-tag, the workflow builds that branch and recursively stages the packages for publishing:

    .github/workflows/release.yml
    name: Release
    
    on:
      workflow_dispatch:
        inputs:
          npm_tag:
            type: choice
            description: 'Specify npm tag'
            required: true
            default: 'alpha'
            options:
              - alpha
              - beta
              - rc
              - latest
          branch:
            description: 'Branch to release'
            required: true
            default: 'main'
    
    permissions: {}
    
    jobs:
      release:
        runs-on: ubuntu-latest
        environment: npm
        permissions:
          contents: read
          id-token: write
        steps:
          - name: Checkout
            uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
            with:
              fetch-depth: 1
              ref: ${{ github.event.inputs.branch }}
    
          - name: Setup Node.js
            uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
            with:
              node-version: 24
    
          - name: Install pnpm
            uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
            with:
              run_install: true
    
          - name: Build
            run: pnpm run build
    
          - name: Publish to npm
            run: |
              pnpm --filter './packages/*' -r stage publish --tag ${{ github.event.inputs.npm_tag }} --no-git-checks

    The top-level permissions: {} disables the default GITHUB_TOKEN permissions. The publishing job only grants contents: read to check out the source and id-token: write for npm OIDC authentication.

    Note

    When configuring Trusted publishing on npm, the repository and workflow filename must match the workflow. If you also configure an Environment for Trusted publishing, use the same name as the npm Environment in the examples above.