Use when bumping Meteor package versions for beta, RC, or official releases. Covers the two version schemes (meteor-tool vs all other packages), the update-semver automation tool, manual files the tool does not handle, and the full lifecycle from beta through official release. Applies to packages/*/package.js, scripts/admin/, npm-packages/meteor-installer/, and .meteor/versions in test apps.
72
88%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
Guidelines for bumping package versions across the Meteor repository for beta, RC, and official releases.
Releases are prepared on release-<VERSION> branches (e.g., release-3.4.1). The main development branch is devel.
devel and the release branchdevel to determine which packages need version bumpsThe track number is the release branch digits concatenated (dots removed):
| Branch | Track Number |
|---|---|
release-3.4 | 340 |
release-3.4.1 | 341 |
release-3.5 | 350 |
git diff devel --dirstat=files -- ./packages/This is the same comparison used by the update-semver automation tool via scripts/admin/update-semver/get-diff.sh.
Before bumping versions:
release-* branch1. meteor-tool — simple semver prerelease (no track number):
| Stage | Format | Example |
|---|---|---|
| Beta | X.Y.Z-beta.N | 3.4.0-beta.0 |
| RC | X.Y.Z-rc.N | 3.4.0-rc.0 |
| Official | X.Y.Z | 3.4.0 |
2. All other packages — encode the track number in the prerelease tag:
| Stage | Format | Example (track 340) |
|---|---|---|
| Beta | X.Y.Z-beta<TRACK>.N | 3.2.0-beta340.0 |
| RC | X.Y.Z-rc<TRACK>.N | 3.2.0-rc340.0 |
| Official | X.Y.Z | 3.2.0 |
| Transition | meteor-tool | Other packages |
|---|---|---|
| Stable to first beta | 3.3.1 -> 3.4.0-beta.0 | 3.1.2 -> 3.2.0-beta340.0 |
| Beta to next beta | 3.4.0-beta.0 -> 3.4.0-beta.1 | 3.2.0-beta340.0 -> 3.2.0-beta340.1 |
| Beta to first RC | 3.4.0-beta.14 -> 3.4.0-rc.0 | 3.2.0-beta340.14 -> 3.2.0-rc340.0 |
| RC to next RC | 3.4.0-rc.0 -> 3.4.0-rc.1 | 3.2.0-rc340.0 -> 3.2.0-rc340.1 |
| RC to official | 3.4.0-rc.4 -> 3.4.0 | 3.2.0-rc340.4 -> 3.2.0 |
When creating the first beta for a release, each changed package needs a version bump from its current stable version. The magnitude depends on the nature of changes.
For subsequent betas, RCs, and official releases, the base version (X.Y.Z) stays the same — only the prerelease suffix changes.
| Magnitude | When to use | Examples |
|---|---|---|
| Patch | Bug fixes, performance improvements, type fixes, internal refactors with no API changes | Fix passwordValidator precedence, remove redundant await, TypeScript type corrections |
| Minor | New public APIs, new exported functions/methods, new user-facing features or capabilities | New getUserIdsInRoleAsync method, new CSS auto-delegation feature, new test assertion methods |
| Major | Breaking changes, removed APIs, renamed exports, changed function signatures | Removed public method, renamed package export, async migration of sync API |
For each changed package, Claude should analyze the diff to determine the bump magnitude:
git diff devel -- packages/<name>/IMPORTANT — Auto-update safety rule: Meteor patch versions are picked up automatically by apps using ~ semver ranges. A patch bump that changes observable behavior can silently break apps on their next update. When in doubt, bump minor — it's always safer. Minor bumps require explicit opt-in, giving users control over when they adopt changes.
Check for minor bump signals:
package.js (api.export, api.addFiles for new files)_-prefixed methods, since Meteor users commonly monkey-patch internalsaddFiles (e.g., *-config-ui packages with OAuth setup instructions) produce different user-visible output when their templates changeCheck for patch bump signals:
.d.ts changes only)return await → return in async function)Check for major bump signals:
package.jsWhen proposing version bumps to the user, always present a table with the reason for each bump decision:
| Package | Current | Bump | New Version | Reason |
|---------|---------|------|-------------|--------|
| roles | 1.0.2 | minor | 1.1.0-betaXXX.0 | **New public API:** `getUserIdsInRoleAsync` added |
| webapp | 2.1.1 | patch | 2.1.2-betaXXX.0 | Removed Vary header — bug fix, no new APIs |
| google-config-ui | 1.0.4 | minor | 1.1.0-betaXXX.0 | **UI content change:** OAuth setup instructions updated — user-facing HTML differs |
| ddp-client | 3.1.1 | minor | 3.2.0-betaXXX.0 | **Removed internal method:** `_processOneDataMessage` — could break monkey-patching |Always get user confirmation before applying the bumps.
When a package in the build plugin chain is bumped, its dependent build plugins must also be bumped — even if they have no code changes. This is because build plugins compile user code, and a change in an upstream compiler dependency can affect the compiled output.
The build plugin chain:
babel-compiler
├── ecmascript (registerBuildPlugin, uses babel-compiler)
├── typescript (registerBuildPlugin, uses babel-compiler)
└── minifier-js (registerBuildPlugin, uses babel-compiler)Rule: If babel-compiler is in the bump list, also bump ecmascript, typescript, and minifier-js. Cascade bumps must match or exceed the upstream magnitude — if babel-compiler gets a minor bump, cascading packages also get minor (unless their own changes warrant major).
This rule applies only to build plugin dependencies (registerBuildPlugin + api.use of the upstream package). It does not apply to:
api.imply a bumped package (e.g., ddp implying ddp-server)accounts-* family that implies accounts-baseapi.useWhen presenting the bump table, mark cascading bumps clearly:
| Package | Current | Bump | New Version | Reason |
|---------|---------|------|-------------|--------|
| babel-compiler | 7.13.0 | patch | 7.13.1-betaXXX.0 | Bug fix in compilation |
| typescript | 5.9.3 | patch | 5.9.4-betaXXX.0 | **Cascade:** depends on babel-compiler (build plugin) |
| ecmascript | 0.17.0 | patch | 0.17.1-betaXXX.0 | **Cascade:** depends on babel-compiler (build plugin) |
| minifier-js | 3.1.0 | patch | 3.1.1-betaXXX.0 | **Cascade:** depends on babel-compiler (build plugin) || File | Beta | RC | Official |
|---|---|---|---|
packages/*/package.js | Yes | Yes | Yes |
scripts/admin/meteor-release-experimental.json | Yes | Yes | No |
scripts/admin/meteor-release-official.json | No | No | Yes |
.meteor/versions in test-apps/ only | Yes | Yes | Yes |
npm-packages/meteor-installer/config.js | No | No | Yes |
npm-packages/meteor-installer/package.json + lock | No | No | Yes |
v3-docs/ (changelog, docs with version refs) | Yes | Yes | Yes |
Claude should perform the version bump process directly rather than relying on the update-semver script. The AI approach is preferred because:
release-* branch and will fail on preparation branchespackages/*/package.js, not release files, .meteor/versions, npm installer, or docsgit diff devel --dirstat=files -- ./packages/package.jspackage.js version edits.meteor/versions, etc.)Given a current stable version and the release branch track number:
X.Y.Z → X.Y.(Z+1)-beta<TRACK>.0X.Y.Z → X.(Y+1).0-beta<TRACK>.0X.Y.Z → (X+1).0.0-beta<TRACK>.0-beta.0 (no track number)update-semver ScriptLocated at scripts/admin/update-semver/. Use only when on a release-* branch and a quick default-patch bump is acceptable.
Limitations:
release-* branch name (fails on other branches)packages/*/package.js — does not touch release files, .meteor/versions, npm installer, or docscd scripts/admin/update-semver
# Auto-bump all changed packages for beta (all patch)
npm run bump-experimental-beta
# Auto-bump all changed packages for RC
npm run bump-experimental-rc
# Bump specific packages with specific magnitudes
node index.js accounts-password.minor babel-compiler.minorgit diff devel --dirstat=files -- ./packages/packages/*/package.js Package.describe versionX.Y.Z-beta<TRACK>.0 for packages, X.Y.Z-beta.0 for meteor-toolEdit scripts/admin/meteor-release-experimental.json:
{
"track": "METEOR",
"version": "X.Y-beta.N",
"recommended": false,
"official": false,
"description": "Meteor experimental release"
}X.Y-beta.N (short form, no patch component)recommended and official are false.meteor/versions in test appsOnly update test apps under test-apps/ (e.g., test-apps/34app/). Do NOT update .meteor/versions in tools/tests/apps/ or tools/e2e-tests/apps/ — those are pinned for CI stability.
find test-apps/ -name "versions" -path "*/.meteor/*"In each file, update only packages that are at prerelease versions (or newly added packages). Leave already-stable package versions untouched.
Note: The set of packages at prerelease versions can grow between beta and RC as more changes are merged to the release branch.
Use the changelog skill to create or update the changelog entry at v3-docs/docs/generators/changelog/versions/<VERSION>.md.
Update the version header date to the current date. Update the Bumped Meteor Packages section in the changelog with all packages that were bumped. Use the version that matches the current release stage — beta versions for beta releases, RC versions for RC releases, and final versions (no prerelease suffix) for official releases. Format: one package per line, name@version. Include meteor-tool@<version> when applicable.
Update any documentation files that reference specific package versions (e.g., rspack installation commands).
Update the prerelease suffix in each packages/*/package.js from beta to RC (or increment RC):
The transitions are:
beta<TRACK>.N -> rc<TRACK>.0 (first RC)rc<TRACK>.N -> rc<TRACK>.N+1 (subsequent RCs)beta.N -> rc.0 (meteor-tool, first RC)rc.N -> rc.N+1 (meteor-tool, subsequent RCs)Edit scripts/admin/meteor-release-experimental.json:
{
"track": "METEOR",
"version": "X.Y-rc.N",
"recommended": false,
"official": false,
"description": "Meteor experimental release"
}.meteor/versions in test appsSame rule as beta: only test-apps/, not tools/tests/apps/ or tools/e2e-tests/apps/. Update only packages at prerelease versions.
Update the version header date to the current date. Update changelog and any docs referencing RC versions. Update the Bumped Meteor Packages section with the current RC versions.
Official releases follow a two-step process (typically two separate commits).
For every packages/*/package.js that has an RC version, remove the -rc<TRACK>.N or -rc.N suffix:
3.2.0-rc340.4 -> 3.2.03.4.0-rc.4 -> 3.4.0 (meteor-tool)Edit scripts/admin/meteor-release-official.json:
{
"track": "METEOR",
"version": "X.Y",
"recommended": false,
"official": true,
"description": "The Official Meteor Distribution"
}.0 releases: short form X.Y (e.g., 3.4)X.Y.Z (e.g., 3.4.1)official must be true.meteor/versions in test appsOnly test-apps/, not tools/tests/apps/ or tools/e2e-tests/apps/. Strip prerelease suffixes from packages that were at RC versions. Leave stable versions untouched.
v3-docs/docs/history.md with the full release entryThis is a separate commit after the packages commit.
Edit npm-packages/meteor-installer/config.js:
const METEOR_LATEST_VERSION = 'X.Y';.0 releases: short form without patch (e.g., '3.4')'3.4.1', '3.3.2')Edit npm-packages/meteor-installer/package.json:
{
"version": "X.Y.Z"
}Full semver form required by npm (e.g., "3.4.0", "3.4.1").
Run npm install in npm-packages/meteor-installer/ to regenerate the lock file, or manually update the version field.
git diff devel --dirstat=files -- ./packages/)packages/*/package.jsscripts/admin/meteor-release-experimental.json version to X.Y.Z-beta.N.meteor/versions in test-apps/ only (not tools/tests/apps/ or tools/e2e-tests/apps/)v3-docs/docs/generators/changelog/versions/packages/*/package.jsscripts/admin/meteor-release-experimental.json version to X.Y.Z-rc.N.meteor/versions in test-apps/ only (not tools/tests/apps/ or tools/e2e-tests/apps/)packages/*/package.jsscripts/admin/meteor-release-official.json (version X.Y, official: true).meteor/versions in test-apps/ only (strip prerelease suffixes)v3-docs/docs/history.mdnpm-packages/meteor-installer/config.js ('X.Y')npm-packages/meteor-installer/package.json ("X.Y.0")npm-packages/meteor-installer/package-lock.json74d90a2
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.