diff --git a/.chronus/changes/node-22-min-2026-3-8-12-27-17.md b/.chronus/changes/node-22-min-2026-3-8-12-27-17.md new file mode 100644 index 00000000000..f96233deba5 --- /dev/null +++ b/.chronus/changes/node-22-min-2026-3-8-12-27-17.md @@ -0,0 +1,34 @@ +--- +# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking +changeKind: internal +packages: + - "@typespec/asset-emitter" + - "@typespec/bundler" + - "@typespec/compiler" + - "@typespec/eslint-plugin" + - "@typespec/events" + - "@typespec/html-program-viewer" + - "@typespec/http-server-csharp" + - "@typespec/http-specs" + - "@typespec/http" + - "@typespec/internal-build-utils" + - "@typespec/json-schema" + - "@typespec/library-linter" + - "@typespec/openapi" + - "@typespec/openapi3" + - "@typespec/playground" + - "@typespec/rest" + - "@typespec/spec-api" + - "@typespec/spec-coverage-sdk" + - "@typespec/spector" + - "@typespec/sse" + - "@typespec/streams" + - tmlanguage-generator + - "@typespec/tspd" + - typespec-vs + - typespec-vscode + - "@typespec/versioning" + - "@typespec/xml" +--- + +Upgrade minimum node version to 22 diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 1429910179d..6c393aedfa5 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -11,7 +11,7 @@ TypeSpec is a language for defining cloud service APIs and shapes. This monorepo ### Prerequisites and Installation -- Install Node.js 20 LTS: `curl -fsSL https://nodejs.org/dist/v20.19.4/node-v20.19.4-linux-x64.tar.xz | tar -xJ --strip-components=1 -C /usr/local` +- Install Node.js LTS: - Install pnpm globally: `npm install -g pnpm` - Install dependencies: `pnpm install` (takes ~1.5 minutes) - Install Playwright browsers (optional for UI testing): `npx playwright install` diff --git a/.github/workflows/core-ci.yml b/.github/workflows/core-ci.yml index 38d69874097..97f2fcdd06e 100644 --- a/.github/workflows/core-ci.yml +++ b/.github/workflows/core-ci.yml @@ -15,7 +15,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest] - node-version: ["20.x", "22.x", "24.x"] + node-version: ["22.x", "24.x"] env: TYPESPEC_VS_CI_BUILD: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fbd408a915a..5bad7dd3d7d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ This section goes over the setup of the repo for development. ## Repo setup -- Install [Node.js](https://nodejs.org/) 20 LTS +- Install [Node.js](https://nodejs.org/) 24 LTS - Install [pnpm](https://pnpm.io/) ```bash diff --git a/docker/Dockerfile b/docker/Dockerfile index 8f5503cc472..4222031370a 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -2,9 +2,7 @@ # Build compiler # -------------------------------- # cspell:ignore tdnf -# mcr doesn't provide any update to date images for nodejs... so we use the devcontainers image for building. -# FROM mcr.microsoft.com/azurelinux/base/nodejs:20.14 AS builder -FROM mcr.microsoft.com/devcontainers/javascript-node:22 AS builder +FROM mcr.microsoft.com/devcontainers/javascript-node:24 AS builder COPY . /app # Upgrade all packages per https://eng.ms/docs/more/containers-secure-supply-chain/updating. @@ -24,7 +22,7 @@ RUN pnpm pack # -------------------------------- # Setup final image # -------------------------------- -FROM mcr.microsoft.com/azurelinux/base/nodejs:20.14 +FROM mcr.microsoft.com/azurelinux/base/nodejs:24 COPY --from=builder /app/packages/compiler/*.tgz /tmp/compiler.tgz diff --git a/eng/tsp-core/pipelines/stages/ci-stages.yml b/eng/tsp-core/pipelines/stages/ci-stages.yml index 15414a1b966..acd7b0bfa54 100644 --- a/eng/tsp-core/pipelines/stages/ci-stages.yml +++ b/eng/tsp-core/pipelines/stages/ci-stages.yml @@ -15,8 +15,6 @@ stages: strategy: matrix: - "Node 20.x": - nodeVersion: 20.x "Node 22.x": nodeVersion: 22.x "Node 24.x": @@ -42,8 +40,6 @@ stages: strategy: matrix: - "Node 20.x": - nodeVersion: 20.x "Node 22.x": nodeVersion: 22.x "Node 24.x": diff --git a/packages/asset-emitter/package.json b/packages/asset-emitter/package.json index 59e84f20b21..bdd16a896e1 100644 --- a/packages/asset-emitter/package.json +++ b/packages/asset-emitter/package.json @@ -23,7 +23,7 @@ } }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/best-practices/package.json b/packages/best-practices/package.json index 22c07908a52..b7fc4cb96c2 100644 --- a/packages/best-practices/package.json +++ b/packages/best-practices/package.json @@ -23,7 +23,7 @@ ".": "./dist/src/index.js" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/bundle-uploader/package.json b/packages/bundle-uploader/package.json index 8be768faefa..b5b89ed87dd 100644 --- a/packages/bundle-uploader/package.json +++ b/packages/bundle-uploader/package.json @@ -20,7 +20,7 @@ "type": "module", "main": "dist/src/index.js", "engines": { - "node": ">=16.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/bundler/package.json b/packages/bundler/package.json index e3dc266b4ea..db778544b25 100644 --- a/packages/bundler/package.json +++ b/packages/bundler/package.json @@ -23,7 +23,7 @@ "./vite": "./dist/src/vite/index.js" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "bundle": "node ./dist/src/cli.js", diff --git a/packages/compiler/package.json b/packages/compiler/package.json index 18e93514fd1..b3fbae4cae5 100644 --- a/packages/compiler/package.json +++ b/packages/compiler/package.json @@ -69,7 +69,7 @@ "./dist/src/core/logger/console-sink.js": "./dist/src/core/logger/console-sink.browser.js" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "bin": { "tsp": "cmd/tsp.js", diff --git a/packages/eslint-plugin-typespec/package.json b/packages/eslint-plugin-typespec/package.json index 7fc4f192084..cacc2ee9ed9 100644 --- a/packages/eslint-plugin-typespec/package.json +++ b/packages/eslint-plugin-typespec/package.json @@ -19,7 +19,7 @@ "type": "commonjs", "main": "dist/src/index.js", "engines": { - "node": ">=14.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/events/package.json b/packages/events/package.json index 7e7d4e5419f..fb531abc728 100644 --- a/packages/events/package.json +++ b/packages/events/package.json @@ -31,7 +31,7 @@ } }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/html-program-viewer/package.json b/packages/html-program-viewer/package.json index 4e13c681034..3e215ca46c6 100644 --- a/packages/html-program-viewer/package.json +++ b/packages/html-program-viewer/package.json @@ -29,7 +29,7 @@ "./style.css": "./dist/style.css" }, "engines": { - "node": ">=14.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/http-server-csharp/package.json b/packages/http-server-csharp/package.json index 7490e02bf53..5564287db62 100644 --- a/packages/http-server-csharp/package.json +++ b/packages/http-server-csharp/package.json @@ -34,7 +34,7 @@ } }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/http-specs/package.json b/packages/http-specs/package.json index 5f1b1f0d59b..b10c2f4eeb4 100644 --- a/packages/http-specs/package.json +++ b/packages/http-specs/package.json @@ -27,7 +27,7 @@ "test": "echo \"Error: no test specified\"" }, "engines": { - "node": ">=16.0.0" + "node": ">=22.0.0" }, "repository": { "type": "git", diff --git a/packages/http/package.json b/packages/http/package.json index 4b98e159e8d..7e7849b9486 100644 --- a/packages/http/package.json +++ b/packages/http/package.json @@ -51,7 +51,7 @@ "#test/*": "./test/*" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/internal-build-utils/package.json b/packages/internal-build-utils/package.json index 5867a10f7f6..6006bb3c62f 100644 --- a/packages/internal-build-utils/package.json +++ b/packages/internal-build-utils/package.json @@ -22,7 +22,7 @@ "typespec-build-tool": "cmd/cli.js" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/json-schema/package.json b/packages/json-schema/package.json index f65a7b93dd3..0299b42054f 100644 --- a/packages/json-schema/package.json +++ b/packages/json-schema/package.json @@ -32,7 +32,7 @@ }, "tspMain": "lib/main.tsp", "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/library-linter/package.json b/packages/library-linter/package.json index 2a7c8ad3bc9..06fcee3e6e4 100644 --- a/packages/library-linter/package.json +++ b/packages/library-linter/package.json @@ -31,7 +31,7 @@ }, "tspMain": "dist/src/index.js", "engines": { - "node": ">=14.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/monarch/package.json b/packages/monarch/package.json index 0d4f708b68f..351d1d937b3 100644 --- a/packages/monarch/package.json +++ b/packages/monarch/package.json @@ -23,7 +23,7 @@ ".": "./dist/src/index.js" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/openapi/package.json b/packages/openapi/package.json index 8b6a1ce8ee5..2f8e15d0a57 100644 --- a/packages/openapi/package.json +++ b/packages/openapi/package.json @@ -31,7 +31,7 @@ } }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/openapi3/package.json b/packages/openapi3/package.json index cb48b898c6c..d66cca5846f 100644 --- a/packages/openapi3/package.json +++ b/packages/openapi3/package.json @@ -37,7 +37,7 @@ "#test/*": "./test/*" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/pack/package.json b/packages/pack/package.json index 4595fa79b77..aad66dafc7e 100644 --- a/packages/pack/package.json +++ b/packages/pack/package.json @@ -26,7 +26,7 @@ "tsp-pack": "cmd/cli.js" }, "engines": { - "node": ">=18.0.0" + "node": ">=22.0.0" }, "scripts": { "bundle": "node ./dist/src/cli.js", diff --git a/packages/playground-website/package.json b/packages/playground-website/package.json index 9e02692cf18..336c67a41ad 100644 --- a/packages/playground-website/package.json +++ b/packages/playground-website/package.json @@ -30,7 +30,7 @@ "./style.css": "./dist/lib/style.css" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./dist-dev ./temp ./samples/dist", diff --git a/packages/playground/package.json b/packages/playground/package.json index 9b88378a812..53e34a7c610 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -51,7 +51,7 @@ "./styles.css": "./dist/style.css" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./dist-dev ./temp ./typespecContents.json", diff --git a/packages/react-components/package.json b/packages/react-components/package.json index aaa4649629e..ce2f31de6b7 100644 --- a/packages/react-components/package.json +++ b/packages/react-components/package.json @@ -27,7 +27,7 @@ "./style.css": "./dist/style.css" }, "engines": { - "node": ">=14.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/rest/package.json b/packages/rest/package.json index 8fa7f4d9c7e..71cd1cb61ea 100644 --- a/packages/rest/package.json +++ b/packages/rest/package.json @@ -31,7 +31,7 @@ } }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/samples/package.json b/packages/samples/package.json index 2d94070ada4..438b6c5afd0 100644 --- a/packages/samples/package.json +++ b/packages/samples/package.json @@ -26,7 +26,7 @@ } }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/spec-api/package.json b/packages/spec-api/package.json index 03692e27cd0..b0d702d8cf5 100644 --- a/packages/spec-api/package.json +++ b/packages/spec-api/package.json @@ -15,7 +15,7 @@ "test": "vitest run" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "repository": { "type": "git", diff --git a/packages/spec-coverage-sdk/package.json b/packages/spec-coverage-sdk/package.json index d97a518d1cc..7c391a29d46 100644 --- a/packages/spec-coverage-sdk/package.json +++ b/packages/spec-coverage-sdk/package.json @@ -10,7 +10,7 @@ "clean": "rimraf dist/ temp/" }, "engines": { - "node": ">=16.0.0" + "node": ">=22.0.0" }, "repository": { "type": "git", diff --git a/packages/spec-dashboard/package.json b/packages/spec-dashboard/package.json index d3c05800ba3..f241c9e0eb0 100644 --- a/packages/spec-dashboard/package.json +++ b/packages/spec-dashboard/package.json @@ -23,7 +23,7 @@ "./style.css": "./dist/style.css" }, "engines": { - "node": ">=16.0.0" + "node": ">=22.0.0" }, "repository": { "type": "git", diff --git a/packages/spector/package.json b/packages/spector/package.json index b8a274b4b6a..ca417d39ce0 100644 --- a/packages/spector/package.json +++ b/packages/spector/package.json @@ -22,7 +22,7 @@ "test:ui": "vitest --ui" }, "engines": { - "node": ">=16.0.0" + "node": ">=22.0.0" }, "repository": { "type": "git", diff --git a/packages/sse/package.json b/packages/sse/package.json index 5fd604493e1..0391e3786c6 100644 --- a/packages/sse/package.json +++ b/packages/sse/package.json @@ -27,7 +27,7 @@ "./testing": "./dist/src/testing/index.js" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/standalone/README.md b/packages/standalone/README.md index 2626d83c1f9..b2754827cfe 100644 --- a/packages/standalone/README.md +++ b/packages/standalone/README.md @@ -2,6 +2,6 @@ This package contains the logic for building and bundling the TypeSpec CLI as a standalone executable. -It requires node 20+ to use node single executable. https://nodejs.org/api/single-executable-applications.html +It requires node 22+ to use node single executable. https://nodejs.org/api/single-executable-applications.html It is also possible to build with bun (code is there) but there is some issue due to signing. Goal will be to migrate to bun when those are resolved. diff --git a/packages/standalone/package.json b/packages/standalone/package.json index 322268d56df..ce82879611c 100644 --- a/packages/standalone/package.json +++ b/packages/standalone/package.json @@ -19,7 +19,7 @@ ], "type": "module", "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/standalone/scripts/build.ts b/packages/standalone/scripts/build.ts index 4492b46413e..5525964047a 100644 --- a/packages/standalone/scripts/build.ts +++ b/packages/standalone/scripts/build.ts @@ -8,8 +8,8 @@ import { writeSeaConfig } from "./sea-config.js"; // cspell:ignore postject const [major, minor, patch] = process.versions.node.split(".").map(Number); -if (major < 20) { - console.error("Cannot build standalone cli on node under 20"); +if (major < 22) { + console.error("Cannot build standalone cli on node under 22"); process.exit(0); } diff --git a/packages/streams/package.json b/packages/streams/package.json index 5cc099832b2..50f344486c0 100644 --- a/packages/streams/package.json +++ b/packages/streams/package.json @@ -31,7 +31,7 @@ } }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/tmlanguage-generator/package.json b/packages/tmlanguage-generator/package.json index b5eeaf4a6b7..c1fac8c16ad 100644 --- a/packages/tmlanguage-generator/package.json +++ b/packages/tmlanguage-generator/package.json @@ -19,7 +19,7 @@ ], "main": "dist/tmlanguage-generator.js", "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/tsp-integration/package.json b/packages/tsp-integration/package.json index 0acc71cd454..71b92870e19 100644 --- a/packages/tsp-integration/package.json +++ b/packages/tsp-integration/package.json @@ -15,7 +15,7 @@ }, "repository": "https://github.com/microsoft/typespec.git", "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "watch": "tsc -p ./tsconfig.build.json --watch", diff --git a/packages/tspd/package.json b/packages/tspd/package.json index 20947c03336..046da030de9 100644 --- a/packages/tspd/package.json +++ b/packages/tspd/package.json @@ -36,7 +36,7 @@ } }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/typespec-vs/package.json b/packages/typespec-vs/package.json index e1b61e9ed95..316f2672d63 100644 --- a/packages/typespec-vs/package.json +++ b/packages/typespec-vs/package.json @@ -18,7 +18,7 @@ ], "type": "module", "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "files": [ "Microsoft.TypeSpec.VS.vsix" diff --git a/packages/typespec-vscode/src/typespec-utils.ts b/packages/typespec-vscode/src/typespec-utils.ts index bb2ce29eeb4..a54a69aee23 100644 --- a/packages/typespec-vscode/src/typespec-utils.ts +++ b/packages/typespec-vscode/src/typespec-utils.ts @@ -75,7 +75,7 @@ export async function installCompilerWithUi( paths: (string | "global")[], ): Promise { const COMPILER_REQUIREMENT = - "Minimum Requirements: Install Node.js 20 LTS or above and verify 'node -v' and 'npm -v' run in command prompt"; + "Minimum Requirements: Install Node.js 22 LTS or above and verify 'node -v' and 'npm -v' run in command prompt"; const globalPath = "global"; if (paths.length === 0) { paths.push(globalPath); diff --git a/packages/versioning/package.json b/packages/versioning/package.json index 40fdfdd2fbd..4e2165aa185 100644 --- a/packages/versioning/package.json +++ b/packages/versioning/package.json @@ -31,7 +31,7 @@ } }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/packages/xml/package.json b/packages/xml/package.json index a8fe32ef7a8..5a538464a9a 100644 --- a/packages/xml/package.json +++ b/packages/xml/package.json @@ -27,7 +27,7 @@ "./testing": "./dist/src/testing/index.js" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "scripts": { "clean": "rimraf ./dist ./temp", diff --git a/website/src/content/docs/docs/extending-typespec/basics.md b/website/src/content/docs/docs/extending-typespec/basics.md index 3bc8134e2f5..632c5c093d3 100644 --- a/website/src/content/docs/docs/extending-typespec/basics.md +++ b/website/src/content/docs/docs/extending-typespec/basics.md @@ -152,8 +152,7 @@ Alternatively, you can add these as scripts in your `package.json` to make them "clean": "rimraf ./dist ./temp", "build": "tsc -p .", "watch": "tsc -p . --watch", - "test": "node --test ./dist/test/**/*.test.js", // Node 22+ - "test": "node --test ./dist/test/" // Node 18, 20 + "test": "node --test ./dist/test/**/*.test.js" } ``` diff --git a/website/src/content/docs/docs/getting-started/getting-started-rest/01-setup-basic-syntax.mdx b/website/src/content/docs/docs/getting-started/getting-started-rest/01-setup-basic-syntax.mdx index 46ae39f3d5c..b9952729831 100644 --- a/website/src/content/docs/docs/getting-started/getting-started-rest/01-setup-basic-syntax.mdx +++ b/website/src/content/docs/docs/getting-started/getting-started-rest/01-setup-basic-syntax.mdx @@ -21,7 +21,7 @@ Before we start writing TypeSpec code, we need to set up our development environ ### Summary of Setup and Installation -1. **Install Node.js**: Download and install Node.js from [nodejs.org](https://nodejs.org/). This will also install npm, the Node.js package manager. The minimum versions required are Node.js 20.0.0 and npm 7.0.0. +1. **Install Node.js**: Download and install Node.js from [nodejs.org](https://nodejs.org/). This will also install npm, the Node.js package manager. The minimum versions required are Node.js 22.0.0 and npm 7.0.0. 2. **Install TypeSpec CLI**: Run `npm install -g @typespec/compiler` to install the TypeSpec CLI. 3. **Verify Installation**: Run `tsp --version` to verify that the TypeSpec CLI is installed correctly. 4. **Create a New Project**: