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.
1---2name: node-migration3description: Migrate Azure/azure-sdk-for-js to a user-specified minimum Node.js version while preserving any existing references above the target.4---56# Azure SDK Node Migration78Migrate the Azure SDK for JavaScript (`Azure/azure-sdk-for-js`) to a user-specified minimum Node.js version.910## When to Use1112Use 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`.1314## Examples1516- "Migrate azure-sdk-for-js to Node 24"17- "Upgrade the repo from Node 22 to Node 24"18- "Raise the minimum Node version to 26"1920## Required Input2122The user must provide a target Node.js version.2324- Treat the target as a major version unless the user explicitly provides full semver.25- If the target is missing or ambiguous, ask for it before editing.26- If the target does not look like an active or plausible Node major version, ask for confirmation.2728Define these values before editing:2930| Name | Meaning |31| --- | --- |32| `TARGET_MAJOR` | User-requested target major, for example `22` or `24`. |33| `TARGET_SEMVER_MIN` | Minimum engine form matching nearby style, usually `>=${TARGET_MAJOR}` or `>=${TARGET_MAJOR}.0.0`. |34| `OLD_SUPPORTED_MAJORS` | Node majors below `TARGET_MAJOR` that appear in Node-runtime contexts. |35| `HIGHER_MAJORS` | Node majors above `TARGET_MAJOR` that appear in Node-runtime contexts and must be preserved. |3637## Core Rules3839- Raise Node.js runtime and minimum-version references below `TARGET_MAJOR` to `TARGET_MAJOR`.40- Preserve Node.js version references above `TARGET_MAJOR`. For example, when target is 22, preserve 24; when target is 24, preserve 26.41- Do not blindly replace every occurrence of the old number.42- 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.43- 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.4445For future migrations, do both passes: broad mechanical sweep first, then a missed-reference sweep.4647## Steps48491. **Verify repo** — Confirm the current repository is `Azure/azure-sdk-for-js`. If not, stop and tell the user this skill expects that repo.502. **Discover current Node references** — Use the Search Checklist to find Node runtime, engine, CI, Docker, docs, lockfile, and generated expectation references.513. **Classify findings** — Separate findings into JSON engine/dependency changes, CI/YAML changes, code/test expectation changes, docs changes, and generated lock/artifact changes.524. **Identify preserved versions** — Record Node majors above `TARGET_MAJOR` and keep them unchanged unless the user explicitly says otherwise.535. **Edit targeted files** — Apply the Core Rules to each finding. Prefer surgical changes and match nearby formatting.546. **Handle special cases** — Use the Special Cases section only when the Core Rules do not fully resolve a finding.557. **Regenerate generated artifacts** — Use repo tooling for lockfiles and generated package artifacts when applicable.568. **Validate** — Run focused checks for changed tooling and a final leftover search.579. **Report outcome** — Include the target version, changed categories, validation performed, and intentionally remaining old references with reasons.5859## Search Checklist6061Target areas to search:6263| Area | Paths / Patterns |64| --- | --- |65| Package engines | `**/package.json` files containing `"node"` in `engines`. |66| Workspace catalog | `pnpm-workspace.yaml` — check `catalog:` entries for `@types/node`. |67| Direct Node setup pins | `.nvmrc`, `.node-version`, `.github/workflows/**`, `eng/pipelines/**`, `rush.json`, `common/config/rush/**`. |68| Dev tooling | `common/tools/dev-tool/**`, `common/tools/eslint-plugin-azure-sdk/**`, `eng/tools/**`, `eng/containers/**`. |69| Docs and Docker | `documentation/**`, `README.md`, `sdk/**/Dockerfile`, `eng/**/Dockerfile`. |70| CI and build scripts | `**/.github/workflows/**`, `**/eng/pipelines/**`, `**/eng/scripts/**`. |71| Review guidelines | `.github/instructions/**`, `.github/prompts/**` — these may reference Node minimum versions as policy. |72| 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. |73| 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. |7475## Special Cases7677- 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.78- Update `@types/node` only when it represents the repo's supported Node typings for tooling or packages. Do not downgrade higher-major typings.79- In CI matrices or dev-tool defaults, remove or raise entries below `TARGET_MAJOR`, but preserve entries above `TARGET_MAJOR`.80- 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.81- Avoid manual lockfile edits when repo tooling can regenerate them correctly.8283## Validation8485Use repo-defined commands only. Inspect `package.json`, `rush.json`, and repo docs before choosing commands.8687Recommended validation:88891. Run the repo install/update command needed to regenerate lock artifacts.902. Run formatting only if existing scripts require it for changed files.913. Run focused checks for touched tooling packages, especially dev-tool and eslint-plugin-azure-sdk if those files changed.924. Run a final leftover search for every old Node major below `TARGET_MAJOR`.935. Search for Node versions above `TARGET_MAJOR` and confirm they were not downgraded.9495## Final Leftover Classification9697For every remaining old-major hit, classify it as one of:9899| Classification | Meaning |100| --- | --- |101| Changed | The reference was updated to `TARGET_MAJOR`. |102| Intentionally preserved: not Node | The number is not a Node.js runtime/minimum reference. |103| Intentionally preserved: above target | The version is above `TARGET_MAJOR` and must remain unchanged. |104| Needs user decision | The reference is ambiguous or the target conflicts with an upper bound. |105106## Troubleshooting107108- If there are many false positives from textual search, narrow to Node-specific contexts before editing.109- If generated files or lockfiles churn unexpectedly, rerun the repo's documented install/update workflow rather than hand-editing generated output.110- 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.111- If `.nvmrc` uses an LTS codename and the correct codename is uncertain, prefer the numeric target major instead of guessing.