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, modern-tool npm package semver analysis, the official installer gate, and the full lifecycle from beta through official release. Applies to packages/*/package.js, scripts/admin/, npm-packages/meteor-installer/, modern-tool npm packages, and .meteor/versions in test apps.
71
88%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
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-* branchInclude changed modern-tool npm packages such as @meteorjs/rspack in the same base-branch analysis:
Compare the full npm package directory with the base. Ignore only its current
version field and matching lockfile version metadata when identifying shipped
changes. Classify the rest as patch, minor, or major, then derive the target
X.Y.Z release line from the base version.
Apply only the explicitly requested npm stage:
| Stage | Target on the required X.Y.Z line |
|---|---|
| Beta | Start at X.Y.Z-beta.0; preserve an existing beta.N or later stage |
| RC | Move beta to X.Y.Z-rc.0; preserve an existing rc.N or stable version |
| Official | Use X.Y.Z without a prerelease suffix |
Never advance a sufficient version just because the workflow reruns. Increment
beta.N or rc.N only when the user requests another prerelease after the
current one was published. If the required magnitude rises, move to the new
release line and reset the requested prerelease to .0. Never downgrade from
RC to beta or from stable to a prerelease.
Do not infer the npm stage from the Meteor release stage. The current
@meteorjs/rspack bump helper supports beta and stable versions, but not RC.
Handle an explicitly requested RC version directly unless that helper changes.
After selecting the package version, use
sync-modern-tool-versions to propagate
it to the lockfile, install constants, normal fixtures, and active docs. The
sync skill verifies the selected version but does not increment it or publish.
Include the npm package in the bump table and apply it after confirmation. Keep
packages/rspack/package.js independent and analyze it normally.
1. 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 |
Some changes don't warrant a version bump at all, even when files in a package change.
A package should not be bumped if its only diff vs devel consists of:
var → const, quote style (' → "), trailing commas,
line-wrap reformatting, indentation, semicolons, function() { → function () {.
No behavioral change.*-tests.js,
*-test.js, tests.js, files under Package.onTest). Tests don't ship to users.If, after mentally stripping out these classes of changes, no runtime code change is left, do not bump the package. The release ships with the package at its current stable version.
Conversely, you MUST bump if any of these are present alongside lint/test/format:
.js / .ts / .mjs file under the package's source (not a test
file) that alters control flow, output, or external behaviorPackage.describe version, summary, dependencies, or exportsNpm.depends() or Cordova.depends() versions.d.ts file that adds/removes/modifies the public type surface
(a semicolon/quote-only .d.ts reformat is still lint-only and does not bump)When unsure whether a diff is lint-only, stop and present the diff to the user.
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/sync-modern-tool-versionspackage.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 entryPrepare a separate installer commit after the packages commit. The official release is incomplete until these values agree:
| File | Required value |
|---|---|
config.js METEOR_LATEST_VERSION | X.Y for X.Y.0; full X.Y.Z for patches |
package.json version | Full npm semver X.Y.Z |
package-lock.json top-level and root versions | Same full npm semver X.Y.Z |
Regenerate the lockfile from npm-packages/meteor-installer/:
npm install --package-lock-only --ignore-scripts
node ../../.github/skills/version-bump/scripts/audit-meteor-installer-version.mjsDo not publish the meteor npm package or complete the official release while
the audit fails. Published npm versions are immutable, so this cannot be fixed
by republishing the same version.
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/sync-modern-tool-versions; resolve audit failurespackages/*/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/)sync-modern-tool-versions; resolve audit failurespackages/*/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.mdsync-modern-tool-versions; resolve audit failuresaudit-meteor-installer-version.mjs02f4d27
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.