From 350367a16723695472cfa6a05050c37603e103e4 Mon Sep 17 00:00:00 2001 From: Jonas Rohde Date: Mon, 30 Mar 2026 16:17:24 +0200 Subject: [PATCH 1/2] chore: add native typecheck rollout --- bun.lock | 19 ++++++++++- docs/plans/decisions-log.md | 44 ++++++++++++++++++++++++++ package.json | 3 ++ templates/apps/api-elysia/package.json | 4 ++- templates/apps/api-hono/package.json | 4 ++- templates/apps/mobile/package.json | 4 ++- templates/apps/web/package.json | 4 ++- templates/base/package.json.hbs | 3 ++ templates/base/turbo.json | 3 ++ templates/packages/shared/package.json | 4 +++ templates/packages/stripe/package.json | 4 +++ templates/packages/ui/package.json | 4 ++- tsconfig.json | 1 + 13 files changed, 95 insertions(+), 6 deletions(-) diff --git a/bun.lock b/bun.lock index 9a3c1b9..248756e 100644 --- a/bun.lock +++ b/bun.lock @@ -10,6 +10,7 @@ }, "devDependencies": { "@types/node": "^22.15.21", + "@typescript/native-preview": "7.0.0-dev.20260321.1", "typescript": "^5.8.3", }, }, @@ -19,7 +20,23 @@ "@clack/prompts": ["@clack/prompts@0.10.1", "", { "dependencies": { "@clack/core": "0.4.2", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-Q0T02vx8ZM9XSv9/Yde0jTmmBQufZhPJfYAg2XrrrxWWaZgq1rr8nU8Hv710BQ1dhoP8rtY7YUdpGej2Qza/cw=="], - "@types/node": ["@types/node@22.19.7", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw=="], + "@types/node": ["@types/node@22.19.15", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg=="], + + "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260321.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260321.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260321.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260321.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260321.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260321.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260321.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260321.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-uScJZRWRxyi1l4EWwOtuO88Gh8sUTi0itcI4oKlyNtXkqik4Y7EHfs1sfYPDuAEJO3cvW6bqohHjGx3mcXSZzQ=="], + + "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260321.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-3LQP363bDCF/pmXqzhSCSkKXr1PpNl2elC167YFRPKRyJdrETiIwj3YAB8A6esn9D30pas5VLzfmeK/tUOf+6g=="], + + "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260321.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-gCoKiv415CROgl0K8hEV8Lw/zvbYriWWmD7VxvpiQiTRqQmHppVXhLtb2OrGaPcsqpoBdYeCJQHN4wnohAkNLA=="], + + "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260321.1", "", { "os": "linux", "cpu": "arm" }, "sha512-QuAFR9eFQzuqtKTIaJ5XkNR4i5Q55b1SE7fUcIAS528aY9j+5P1cMpvJa8aOBCuRKxfMgV5UtamolZKGWWzaMw=="], + + "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260321.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-15z7UWt0PG870ktcUbaa0NogAjXIYT4pSFWlsc95u8+1aITrBTMQgqRih5qUH8bHke3eeYwbpjfXaU4gNmexvw=="], + + "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260321.1", "", { "os": "linux", "cpu": "x64" }, "sha512-8yuzwkxQnNSpXjXK43Y5Pn6rBfNbJVIcd3Qh9n3Tzhgtr+lcoGgwgMvn8axnqaazkxIUB3PZuiGRcqr6XIq3LA=="], + + "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260321.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-fCUk/VElUjMFmE6iFAtsy5r7kLxeLggEHOTWuR0HGYIUQze6EyAdDFqMPFFxvbzpUyFQFpRfUa0I/Fa5tqKh8g=="], + + "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260321.1", "", { "os": "win32", "cpu": "x64" }, "sha512-CWGyck7+sbNwOhcL+ObHhtKZe2/+Y6OZlEdWX2mHjpv8ef7ohUbPCdS94p+e7jbVY56w8NAce2Xx7ppn/C1Ucg=="], "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], diff --git a/docs/plans/decisions-log.md b/docs/plans/decisions-log.md index c4b3d25..49e362f 100644 --- a/docs/plans/decisions-log.md +++ b/docs/plans/decisions-log.md @@ -13,3 +13,47 @@ This keeps the same scaffold behavior while reducing direct dependencies and ali ### Consequences The CLI depends on fewer packages, generated deployment templates now include `.dockerignore`, and deployment-disabled scaffolds remove that file together with `Dockerfile` and `fly.toml`. + +## ADR-2026-03-30-typescript-native-template-rollout + +### Context + +`create-edhor-stack` is both a TypeScript CLI and a scaffolder for Bun/Turborepo TypeScript projects. A native TypeScript rollout that only changes the CLI would leave newly generated projects on the old contract, while a full generated-project smoke fixture would expand scope beyond the current migration pass. + +### Decision + +Roll out the native TypeScript contract at two levels: + +- the CLI repo itself gets `typecheck` and `typecheck:tsc` +- the shipped root and package templates get matching `typecheck` and `typecheck:tsc` scripts, plus a root `@typescript/native-preview` dependency and Turbo fallback task wiring + +Skip the extra generated-project smoke fixture in this pass. + +### Rationale + +This keeps the change aligned with the purpose of the repo. The CLI becomes native-ready, and future scaffolded projects inherit the same contract immediately. Skipping the generated fixture keeps the branch focused and avoids turning one repo migration into a broader template QA project. + +### Consequences + +- the repo can be verified directly +- generated projects will expose native typecheck commands without additional manual setup +- template runtime compatibility is still validated later when a real generated project uses the updated templates + +## ADR-2026-03-30-explicit-node-types-for-native-cli-check + +### Context + +After rebasing the rollout branch onto the newer `main`, the CLI source used `node:*` imports and `process`. Classic `tsc` still passed, but `tsgo` required explicit Node ambient types in the root config. + +### Decision + +Add `"types": ["node"]` to the root CLI `tsconfig.json`. + +### Rationale + +This is the smallest compatibility fix for the native checker and keeps the CLI contract explicit. + +### Consequences + +- `tsgo` and `tsc` align again on the CLI repo +- the change stays local to the root config and does not alter runtime behavior diff --git a/package.json b/package.json index 6441195..cb6b449 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "scripts": { "dev": "bun run src/index.ts", "build": "bun build src/index.ts --outdir dist --target node", + "typecheck": "tsgo --noEmit -p tsconfig.json", + "typecheck:tsc": "tsc --noEmit -p tsconfig.json", "prepublishOnly": "bun run build" }, "keywords": [ @@ -35,6 +37,7 @@ "picocolors": "^1.1.1" }, "devDependencies": { + "@typescript/native-preview": "7.0.0-dev.20260321.1", "@types/node": "^22.15.21", "typescript": "^5.8.3" } diff --git a/templates/apps/api-elysia/package.json b/templates/apps/api-elysia/package.json index c9f4e35..d40e06b 100644 --- a/templates/apps/api-elysia/package.json +++ b/templates/apps/api-elysia/package.json @@ -5,7 +5,9 @@ "scripts": { "dev": "bun run --hot src/index.ts", "start": "bun run src/index.ts", - "test": "bun test" + "test": "bun test", + "typecheck": "tsgo --noEmit -p tsconfig.json", + "typecheck:tsc": "tsc --noEmit -p tsconfig.json" }, "dependencies": { "elysia": "^1.2.0", diff --git a/templates/apps/api-hono/package.json b/templates/apps/api-hono/package.json index 67d0386..9251a87 100644 --- a/templates/apps/api-hono/package.json +++ b/templates/apps/api-hono/package.json @@ -5,7 +5,9 @@ "scripts": { "dev": "bun run --hot src/index.ts", "start": "bun run src/index.ts", - "test": "bun test" + "test": "bun test", + "typecheck": "tsgo --noEmit -p tsconfig.json", + "typecheck:tsc": "tsc --noEmit -p tsconfig.json" }, "dependencies": { "hono": "^4.7.0", diff --git a/templates/apps/mobile/package.json b/templates/apps/mobile/package.json index a8ef938..255eb43 100644 --- a/templates/apps/mobile/package.json +++ b/templates/apps/mobile/package.json @@ -7,7 +7,9 @@ "dev": "expo start", "android": "expo run:android", "ios": "expo run:ios", - "build": "eas build" + "build": "eas build", + "typecheck": "tsgo --noEmit -p tsconfig.json", + "typecheck:tsc": "tsc --noEmit -p tsconfig.json" }, "dependencies": { "expo": "~54.0.0", diff --git a/templates/apps/web/package.json b/templates/apps/web/package.json index 9e3113e..3628650 100644 --- a/templates/apps/web/package.json +++ b/templates/apps/web/package.json @@ -5,7 +5,9 @@ "scripts": { "dev": "vite", "build": "vite build", - "start": "node .output/server/index.mjs" + "start": "node .output/server/index.mjs", + "typecheck": "tsgo --noEmit -p tsconfig.json", + "typecheck:tsc": "tsc --noEmit -p tsconfig.json" }, "dependencies": { "@tanstack/react-router": "^1.154.14", diff --git a/templates/base/package.json.hbs b/templates/base/package.json.hbs index 28e42d4..14c8b57 100644 --- a/templates/base/package.json.hbs +++ b/templates/base/package.json.hbs @@ -5,6 +5,8 @@ "scripts": { "dev": "turbo dev", "build": "turbo build", + "typecheck": "turbo run typecheck", + "typecheck:tsc": "turbo run typecheck:tsc", "lint": "biome lint .", "format": "biome format --write .", "check": "biome check --write .", @@ -13,6 +15,7 @@ }, "devDependencies": { "@biomejs/biome": "2.3.11", + "@typescript/native-preview": "7.0.0-dev.20260321.1", "husky": "^9.1.7", "lint-staged": "^16.1.0", "turbo": "^2.5.4", diff --git a/templates/base/turbo.json b/templates/base/turbo.json index 35f6e0d..cf2fab9 100644 --- a/templates/base/turbo.json +++ b/templates/base/turbo.json @@ -15,6 +15,9 @@ "typecheck": { "dependsOn": ["^build"] }, + "typecheck:tsc": { + "dependsOn": ["^build"] + }, "clean": { "cache": false } diff --git a/templates/packages/shared/package.json b/templates/packages/shared/package.json index a202ccc..53738dc 100644 --- a/templates/packages/shared/package.json +++ b/templates/packages/shared/package.json @@ -8,6 +8,10 @@ "./types": "./src/types.ts", "./utils": "./src/utils.ts" }, + "scripts": { + "typecheck": "tsgo --noEmit -p tsconfig.json", + "typecheck:tsc": "tsc --noEmit -p tsconfig.json" + }, "dependencies": { "zod": "^3.24.0" }, diff --git a/templates/packages/stripe/package.json b/templates/packages/stripe/package.json index 4fd03ea..6353b75 100644 --- a/templates/packages/stripe/package.json +++ b/templates/packages/stripe/package.json @@ -8,6 +8,10 @@ "./webhooks": "./src/webhooks.ts", "./schemas": "./src/schemas.ts" }, + "scripts": { + "typecheck": "tsgo --noEmit -p tsconfig.json", + "typecheck:tsc": "tsc --noEmit -p tsconfig.json" + }, "dependencies": { "stripe": "^17.0.0", "zod": "^3.24.0" diff --git a/templates/packages/ui/package.json b/templates/packages/ui/package.json index 7d4c6f7..5cd84cc 100644 --- a/templates/packages/ui/package.json +++ b/templates/packages/ui/package.json @@ -10,7 +10,9 @@ "./styles.css": "./src/styles.css" }, "scripts": { - "ui:add": "bunx shadcn@latest add" + "ui:add": "bunx shadcn@latest add", + "typecheck": "tsgo --noEmit -p tsconfig.json", + "typecheck:tsc": "tsc --noEmit -p tsconfig.json" }, "dependencies": { "@radix-ui/react-slot": "^1.1.0", diff --git a/tsconfig.json b/tsconfig.json index 32b6993..97c7c0b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "strict": true, "esModuleInterop": true, "skipLibCheck": true, + "types": ["node"], "outDir": "dist", "rootDir": "src", "declaration": true, From 663822b570eba0bd0874258e0a2aba4f92f82cfe Mon Sep 17 00:00:00 2001 From: Jonas Rohde Date: Mon, 30 Mar 2026 18:20:08 +0200 Subject: [PATCH 2/2] docs: add template validation tracker --- docs/plans/decisions-log.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/decisions-log.md b/docs/plans/decisions-log.md index 49e362f..efeb3b6 100644 --- a/docs/plans/decisions-log.md +++ b/docs/plans/decisions-log.md @@ -37,7 +37,7 @@ This keeps the change aligned with the purpose of the repo. The CLI becomes nati - the repo can be verified directly - generated projects will expose native typecheck commands without additional manual setup -- template runtime compatibility is still validated later when a real generated project uses the updated templates +- template runtime compatibility is still validated later when a real generated project uses the updated templates; TODO tracking: issue `#TBD` before merge, owner `@edhor1608`, target date `2026-04-06` ## ADR-2026-03-30-explicit-node-types-for-native-cli-check