| name | node-migration |
| description | Migrate Azure/azure-sdk-for-js to a user-specified minimum Node.js version while preserving any existing references above the target. |
Azure SDK Node Migration
Migrate the Azure SDK for JavaScript (Azure/azure-sdk-for-js) to a user-specified minimum Node.js version.
When to Use
Use this skill when the user asks to upgrade, migrate, or raise the repo-wide Node.js minimum or supported version for Azure/azure-sdk-for-js.
Examples
- "Migrate azure-sdk-for-js to Node 24"
- "Upgrade the repo from Node 22 to Node 24"
- "Raise the minimum Node version to 26"
Required Input
The user must provide a target Node.js version.
- Treat the target as a major version unless the user explicitly provides full semver.
- If the target is missing or ambiguous, ask for it before editing.
- If the target does not look like an active or plausible Node major version, ask for confirmation.
Define these values before editing:
| Name | Meaning |
|---|
TARGET_MAJOR | User-requested target major, for example 22 or 24. |
TARGET_SEMVER_MIN | Minimum engine form matching nearby style, usually >=${TARGET_MAJOR} or >=${TARGET_MAJOR}.0.0. |
OLD_SUPPORTED_MAJORS | Node majors below TARGET_MAJOR that appear in Node-runtime contexts. |
HIGHER_MAJORS | Node majors above TARGET_MAJOR that appear in Node-runtime contexts and must be preserved. |
Core Rules
- Raise Node.js runtime and minimum-version references below
TARGET_MAJOR to TARGET_MAJOR.
- Preserve Node.js version references above
TARGET_MAJOR. For example, when target is 22, preserve 24; when target is 24, preserve 26.
- Do not blindly replace every occurrence of the old number.
- Only change references that are clearly Node.js runtime, Node engine, Node typing, CI setup, Docker default, documentation, lock/generated artifact, or related test expectation references.
- Do not change unrelated API versions, service versions, years, port numbers, sample data, or dependency versions where the number is not clearly a Node.js version.
For future migrations, do both passes: broad mechanical sweep first, then a missed-reference sweep.
Steps
- Verify repo — Confirm the current repository is
Azure/azure-sdk-for-js. If not, stop and tell the user this skill expects that repo.
- Discover current Node references — Use the Search Checklist to find Node runtime, engine, CI, Docker, docs, lockfile, and generated expectation references.
- Classify findings — Separate findings into JSON engine/dependency changes, CI/YAML changes, code/test expectation changes, docs changes, and generated lock/artifact changes.
- Identify preserved versions — Record Node majors above
TARGET_MAJOR and keep them unchanged unless the user explicitly says otherwise.
- Edit targeted files — Apply the Core Rules to each finding. Prefer surgical changes and match nearby formatting.
- Handle special cases — Use the Special Cases section only when the Core Rules do not fully resolve a finding.
- Regenerate generated artifacts — Use repo tooling for lockfiles and generated package artifacts when applicable.
- Validate — Run focused checks for changed tooling and a final leftover search.
- Report outcome — Include the target version, changed categories, validation performed, and intentionally remaining old references with reasons.
Search Checklist
Target areas to search:
| Area | Paths / Patterns |
|---|
| Package engines | **/package.json files containing "node" in engines. |
| Workspace catalog | pnpm-workspace.yaml — check catalog: entries for @types/node. |
| Direct Node setup pins | .nvmrc, .node-version, .github/workflows/**, eng/pipelines/**, rush.json, common/config/rush/**. |
| Dev tooling | common/tools/dev-tool/**, common/tools/eslint-plugin-azure-sdk/**, eng/tools/**, eng/containers/**. |
| Docs and Docker | documentation/**, README.md, sdk/**/Dockerfile, eng/**/Dockerfile. |
| CI and build scripts | **/.github/workflows/**, **/eng/pipelines/**, **/eng/scripts/**. |
| Review guidelines | .github/instructions/**, .github/prompts/** — these may reference Node minimum versions as policy. |
| SDK packages (bulk) | All sdk/**/package.json engine fields and sdk/**/samples/**/package.json @types/node entries. These are enforced by the eslint rule and dev-tool, so update them in bulk after updating the tooling constants. |
| Textual leftovers | For each old major X: Node.js X, Node X, node-version: "X", node-version: X, NODE_VERSION=X, >=X, >=X.0.0, @types/node@X, @types/node": "X, @types/node": "^X, and known LTS codenames if relevant. |
Special Cases
- If an engine range has an upper bound, update the lower bound only when the resulting range remains valid. If
TARGET_MAJOR conflicts with the upper bound, ask the user how to handle it.
- Update
@types/node only when it represents the repo's supported Node typings for tooling or packages. Do not downgrade higher-major typings.
- In CI matrices or dev-tool defaults, remove or raise entries below
TARGET_MAJOR, but preserve entries above TARGET_MAJOR.
- For
.nvmrc or .node-version, prefer the repo's existing convention. If the correct LTS codename is uncertain, use the numeric target major rather than guessing.
- Avoid manual lockfile edits when repo tooling can regenerate them correctly.
Validation
Use repo-defined commands only. Inspect package.json, rush.json, and repo docs before choosing commands.
Recommended validation:
- Run the repo install/update command needed to regenerate lock artifacts.
- Run formatting only if existing scripts require it for changed files.
- Run focused checks for touched tooling packages, especially dev-tool and eslint-plugin-azure-sdk if those files changed.
- Run a final leftover search for every old Node major below
TARGET_MAJOR.
- Search for Node versions above
TARGET_MAJOR and confirm they were not downgraded.
Final Leftover Classification
For every remaining old-major hit, classify it as one of:
| Classification | Meaning |
|---|
| Changed | The reference was updated to TARGET_MAJOR. |
| Intentionally preserved: not Node | The number is not a Node.js runtime/minimum reference. |
| Intentionally preserved: above target | The version is above TARGET_MAJOR and must remain unchanged. |
| Needs user decision | The reference is ambiguous or the target conflicts with an upper bound. |
Troubleshooting
- If there are many false positives from textual search, narrow to Node-specific contexts before editing.
- If generated files or lockfiles churn unexpectedly, rerun the repo's documented install/update workflow rather than hand-editing generated output.
- If a package engine range has an upper bound lower than
TARGET_MAJOR, stop and ask the user whether to raise the upper bound, skip that package, or handle it separately.
- If
.nvmrc uses an LTS codename and the correct codename is uncertain, prefer the numeric target major instead of guessing.