From c69b176c386d2e64cfaafff498ecee7fb04014ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 18:18:40 +0200 Subject: [PATCH 01/25] fix: use v16-appRouter MUI import path - CNA pinned to v16; v15 path broke MUI + App Router on Next 16 --- packages/create-next-stack/src/main/plugins/material-ui.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-next-stack/src/main/plugins/material-ui.ts b/packages/create-next-stack/src/main/plugins/material-ui.ts index 518ddb1..ee86dd9 100644 --- a/packages/create-next-stack/src/main/plugins/material-ui.ts +++ b/packages/create-next-stack/src/main/plugins/material-ui.ts @@ -84,7 +84,7 @@ export const materialUIPlugin: Plugin = { htmlAttributes: `className={roboto.variable}`, headContent: ``, providerImports: aldent` - import { AppRouterCacheProvider } from "@mui/material-nextjs/v15-appRouter"; + import { AppRouterCacheProvider } from "@mui/material-nextjs/v16-appRouter"; import { ThemeProvider as MuiThemeProvider } from "@mui/material/styles"; import CssBaseline from "@mui/material/CssBaseline"; import materialTheme from "../material-theme"; From ea1e3d2afe330c1ea797ab241e7d0608e3a5aaeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 18:20:07 +0200 Subject: [PATCH 02/25] chore: bump next-plausible ^3 -> ^4 - v4 adds Next.js 16 support; generated projects use CNA v16 --- packages/create-next-stack/src/main/plugins/plausible.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-next-stack/src/main/plugins/plausible.ts b/packages/create-next-stack/src/main/plugins/plausible.ts index f53d957..f8935f1 100644 --- a/packages/create-next-stack/src/main/plugins/plausible.ts +++ b/packages/create-next-stack/src/main/plugins/plausible.ts @@ -8,7 +8,7 @@ export const plausiblePlugin: Plugin = { name: "Plausible", description: "Adds support for Plausible Analytics", active: ({ flags }) => flags["plausible"], - dependencies: [{ name: "next-plausible", version: "^3.0.0" }], + dependencies: [{ name: "next-plausible", version: "^4.0.0" }], technologies: [ { id: "plausible", From 090dd96534fec0fef7abb3a143a44321541ff7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 18:23:17 +0200 Subject: [PATCH 03/25] chore: bump typescript ^5 -> ^6 - root + CLI package.json - typescript-eslint ^8.56 -> ^8.58.1 (peer support for TS 6) - website: add globals.d.ts w/ CSS side-effect decl (TS 6 stricter) --- apps/website/globals.d.ts | 1 + package.json | 2 +- packages/create-next-stack/package.json | 4 +- pnpm-lock.yaml | 311 ++++++++++++++++-------- 4 files changed, 219 insertions(+), 99 deletions(-) create mode 100644 apps/website/globals.d.ts diff --git a/apps/website/globals.d.ts b/apps/website/globals.d.ts new file mode 100644 index 0000000..d7e961e --- /dev/null +++ b/apps/website/globals.d.ts @@ -0,0 +1 @@ +declare module "*.css" diff --git a/package.json b/package.json index 6f1be6e..2640cb5 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "lint-staged": "^15.4.3", "prettier": "^3.5.3", "turbo": "^2.4.4", - "typescript": "^5.8.2" + "typescript": "^6.0.2" }, "lint-staged": { "*": "prettier --write --ignore-unknown" diff --git a/packages/create-next-stack/package.json b/packages/create-next-stack/package.json index a33d779..685e06e 100644 --- a/packages/create-next-stack/package.json +++ b/packages/create-next-stack/package.json @@ -92,8 +92,8 @@ "eslint": "^10.0.0", "eslint-config-prettier": "^10.1.1", "next": "^16.0.0", - "typescript": "^5.8.2", - "typescript-eslint": "^8.56.0", + "typescript": "^6.0.2", + "typescript-eslint": "^8.58.1", "uuid": "^9.0.0", "vitest": "^4.0.18" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4af2a87..1b9712a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,8 +21,8 @@ importers: specifier: ^2.4.4 version: 2.8.12 typescript: - specifier: ^5.8.2 - version: 5.9.3 + specifier: ^6.0.2 + version: 6.0.2 apps/website: dependencies: @@ -62,7 +62,7 @@ importers: version: 9.39.3 eslint-config-next: specifier: ^16.0.0 - version: 16.1.6(eslint@9.39.3)(typescript@5.9.3) + version: 16.1.6(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3)(typescript@6.0.2) eslint-config-prettier: specifier: ^10.0.0 version: 10.1.8(eslint@9.39.3) @@ -134,11 +134,11 @@ importers: specifier: ^16.0.0 version: 16.1.6(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) typescript: - specifier: ^5.8.2 - version: 5.9.3 + specifier: ^6.0.2 + version: 6.0.2 typescript-eslint: - specifier: ^8.56.0 - version: 8.56.1(eslint@10.0.2)(typescript@5.9.3) + specifier: ^8.58.1 + version: 8.58.1(eslint@10.0.2)(typescript@6.0.2) uuid: specifier: ^9.0.0 version: 9.0.1 @@ -970,6 +970,14 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/eslint-plugin@8.58.1': + resolution: {integrity: sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.58.1 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/parser@8.56.1': resolution: {integrity: sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -977,22 +985,45 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/parser@8.58.1': + resolution: {integrity: sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/project-service@8.56.1': resolution: {integrity: sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/project-service@8.58.1': + resolution: {integrity: sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/scope-manager@8.56.1': resolution: {integrity: sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.58.1': + resolution: {integrity: sha512-TPYUEqJK6avLcEjumWsIuTpuYODTTDAtoMdt8ZZa93uWMTX13Nb8L5leSje1NluammvU+oI3QRr5lLXPgihX3w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/tsconfig-utils@8.56.1': resolution: {integrity: sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/tsconfig-utils@8.58.1': + resolution: {integrity: sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/type-utils@8.56.1': resolution: {integrity: sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1000,16 +1031,33 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/type-utils@8.58.1': + resolution: {integrity: sha512-HUFxvTJVroT+0rXVJC7eD5zol6ID+Sn5npVPWoFuHGg9Ncq5Q4EYstqR+UOqaNRFXi5TYkpXXkLhoCHe3G0+7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/types@8.56.1': resolution: {integrity: sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.58.1': + resolution: {integrity: sha512-io/dV5Aw5ezwzfPBBWLoT+5QfVtP8O7q4Kftjn5azJ88bYyp/ZMCsyW1lpKK46EXJcaYMZ1JtYj+s/7TdzmQMw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.56.1': resolution: {integrity: sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/typescript-estree@8.58.1': + resolution: {integrity: sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/utils@8.56.1': resolution: {integrity: sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1017,10 +1065,21 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/utils@8.58.1': + resolution: {integrity: sha512-Ln8R0tmWC7pTtLOzgJzYTXSCjJ9rDNHAqTaVONF4FEi2qwce8mD9iSOxOpLFFvWp/wBFlew0mjM1L1ihYWfBdQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/visitor-keys@8.56.1': resolution: {integrity: sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.58.1': + resolution: {integrity: sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@unrs/resolver-binding-android-arm-eabi@1.11.1': resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} cpu: [arm] @@ -2844,6 +2903,12 @@ packages: peerDependencies: typescript: '>=4.8.4' + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} @@ -2919,8 +2984,15 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + typescript-eslint@8.58.1: + resolution: {integrity: sha512-gf6/oHChByg9HJvhMO1iBexJh12AqqTfnuxscMDOVqfJW3htsdRJI/GfPpHTTcyeB8cSTUY2JcZmVgoyPqcrDg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + typescript@6.0.2: + resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==} engines: {node: '>=14.17'} hasBin: true @@ -3833,68 +3905,77 @@ snapshots: '@types/validate-npm-package-name@4.0.2': {} - '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@10.0.2)(typescript@5.9.3))(eslint@10.0.2)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3)(typescript@6.0.2)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.56.1(eslint@10.0.2)(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.1(eslint@9.39.3)(typescript@6.0.2) '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/type-utils': 8.56.1(eslint@10.0.2)(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@10.0.2)(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.56.1(eslint@9.39.3)(typescript@6.0.2) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.3)(typescript@6.0.2) '@typescript-eslint/visitor-keys': 8.56.1 - eslint: 10.0.2 + eslint: 9.39.3 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 + ts-api-utils: 2.4.0(typescript@6.0.2) + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@5.9.3))(eslint@9.39.3)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.58.1(@typescript-eslint/parser@8.58.1(eslint@10.0.2)(typescript@6.0.2))(eslint@10.0.2)(typescript@6.0.2)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.56.1(eslint@9.39.3)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/type-utils': 8.56.1(eslint@9.39.3)(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@9.39.3)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.56.1 - eslint: 9.39.3 + '@typescript-eslint/parser': 8.58.1(eslint@10.0.2)(typescript@6.0.2) + '@typescript-eslint/scope-manager': 8.58.1 + '@typescript-eslint/type-utils': 8.58.1(eslint@10.0.2)(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.1(eslint@10.0.2)(typescript@6.0.2) + '@typescript-eslint/visitor-keys': 8.58.1 + eslint: 10.0.2 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 + ts-api-utils: 2.5.0(typescript@6.0.2) + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.56.1(eslint@10.0.2)(typescript@5.9.3)': + '@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2)': dependencies: '@typescript-eslint/scope-manager': 8.56.1 '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.56.1(typescript@6.0.2) '@typescript-eslint/visitor-keys': 8.56.1 debug: 4.4.3(supports-color@8.1.1) + eslint: 9.39.3 + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.58.1(eslint@10.0.2)(typescript@6.0.2)': + dependencies: + '@typescript-eslint/scope-manager': 8.58.1 + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/typescript-estree': 8.58.1(typescript@6.0.2) + '@typescript-eslint/visitor-keys': 8.58.1 + debug: 4.4.3(supports-color@8.1.1) eslint: 10.0.2 - typescript: 5.9.3 + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@5.9.3)': + '@typescript-eslint/project-service@8.56.1(typescript@6.0.2)': dependencies: - '@typescript-eslint/scope-manager': 8.56.1 + '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@6.0.2) '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.56.1 debug: 4.4.3(supports-color@8.1.1) - eslint: 9.39.3 - typescript: 5.9.3 + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.56.1(typescript@5.9.3)': + '@typescript-eslint/project-service@8.58.1(typescript@6.0.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) - '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/tsconfig-utils': 8.58.1(typescript@6.0.2) + '@typescript-eslint/types': 8.58.1 debug: 4.4.3(supports-color@8.1.1) - typescript: 5.9.3 + typescript: 6.0.2 transitivePeerDependencies: - supports-color @@ -3903,70 +3984,96 @@ snapshots: '@typescript-eslint/types': 8.56.1 '@typescript-eslint/visitor-keys': 8.56.1 - '@typescript-eslint/tsconfig-utils@8.56.1(typescript@5.9.3)': + '@typescript-eslint/scope-manager@8.58.1': + dependencies: + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/visitor-keys': 8.58.1 + + '@typescript-eslint/tsconfig-utils@8.56.1(typescript@6.0.2)': + dependencies: + typescript: 6.0.2 + + '@typescript-eslint/tsconfig-utils@8.58.1(typescript@6.0.2)': dependencies: - typescript: 5.9.3 + typescript: 6.0.2 - '@typescript-eslint/type-utils@8.56.1(eslint@10.0.2)(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.56.1(eslint@9.39.3)(typescript@6.0.2)': dependencies: '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@10.0.2)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.56.1(typescript@6.0.2) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.3)(typescript@6.0.2) debug: 4.4.3(supports-color@8.1.1) - eslint: 10.0.2 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 + eslint: 9.39.3 + ts-api-utils: 2.4.0(typescript@6.0.2) + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.56.1(eslint@9.39.3)(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.58.1(eslint@10.0.2)(typescript@6.0.2)': dependencies: - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@9.39.3)(typescript@5.9.3) + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/typescript-estree': 8.58.1(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.1(eslint@10.0.2)(typescript@6.0.2) debug: 4.4.3(supports-color@8.1.1) - eslint: 9.39.3 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 + eslint: 10.0.2 + ts-api-utils: 2.5.0(typescript@6.0.2) + typescript: 6.0.2 transitivePeerDependencies: - supports-color '@typescript-eslint/types@8.56.1': {} - '@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3)': + '@typescript-eslint/types@8.58.1': {} + + '@typescript-eslint/typescript-estree@8.56.1(typescript@6.0.2)': dependencies: - '@typescript-eslint/project-service': 8.56.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) + '@typescript-eslint/project-service': 8.56.1(typescript@6.0.2) + '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@6.0.2) '@typescript-eslint/types': 8.56.1 '@typescript-eslint/visitor-keys': 8.56.1 debug: 4.4.3(supports-color@8.1.1) minimatch: 10.2.4 semver: 7.7.4 tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 + ts-api-utils: 2.4.0(typescript@6.0.2) + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.56.1(eslint@10.0.2)(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.58.1(typescript@6.0.2)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2) - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - eslint: 10.0.2 - typescript: 5.9.3 + '@typescript-eslint/project-service': 8.58.1(typescript@6.0.2) + '@typescript-eslint/tsconfig-utils': 8.58.1(typescript@6.0.2) + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/visitor-keys': 8.58.1 + debug: 4.4.3(supports-color@8.1.1) + minimatch: 10.2.4 + semver: 7.7.4 + tinyglobby: 0.2.15 + ts-api-utils: 2.5.0(typescript@6.0.2) + typescript: 6.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.56.1(eslint@9.39.3)(typescript@5.9.3)': + '@typescript-eslint/utils@8.56.1(eslint@9.39.3)(typescript@6.0.2)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3) '@typescript-eslint/scope-manager': 8.56.1 '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.56.1(typescript@6.0.2) eslint: 9.39.3 - typescript: 5.9.3 + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.58.1(eslint@10.0.2)(typescript@6.0.2)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2) + '@typescript-eslint/scope-manager': 8.58.1 + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/typescript-estree': 8.58.1(typescript@6.0.2) + eslint: 10.0.2 + typescript: 6.0.2 transitivePeerDependencies: - supports-color @@ -3975,6 +4082,11 @@ snapshots: '@typescript-eslint/types': 8.56.1 eslint-visitor-keys: 5.0.1 + '@typescript-eslint/visitor-keys@8.58.1': + dependencies: + '@typescript-eslint/types': 8.58.1 + eslint-visitor-keys: 5.0.1 + '@unrs/resolver-binding-android-arm-eabi@1.11.1': optional: true @@ -4539,20 +4651,20 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-next@16.1.6(eslint@9.39.3)(typescript@5.9.3): + eslint-config-next@16.1.6(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3)(typescript@6.0.2): dependencies: '@next/eslint-plugin-next': 16.1.6 eslint: 9.39.3 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(eslint@9.39.3))(eslint@9.39.3) - eslint-plugin-import: 2.32.0(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3))(eslint@9.39.3) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.3) eslint-plugin-react: 7.37.5(eslint@9.39.3) eslint-plugin-react-hooks: 7.0.1(eslint@9.39.3) globals: 16.4.0 - typescript-eslint: 8.56.1(eslint@9.39.3)(typescript@5.9.3) + typescript-eslint: 8.56.1(eslint@9.39.3)(typescript@6.0.2) optionalDependencies: - typescript: 5.9.3 + typescript: 6.0.2 transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-webpack @@ -4575,7 +4687,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@9.39.3))(eslint@9.39.3): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3(supports-color@8.1.1) @@ -4586,21 +4698,22 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3))(eslint@9.39.3) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@9.39.3))(eslint@9.39.3))(eslint@9.39.3): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3))(eslint@9.39.3): dependencies: debug: 3.2.7 optionalDependencies: + '@typescript-eslint/parser': 8.56.1(eslint@9.39.3)(typescript@6.0.2) eslint: 9.39.3 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(eslint@9.39.3))(eslint@9.39.3) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3))(eslint@9.39.3): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -4611,7 +4724,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.3 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@9.39.3))(eslint@9.39.3))(eslint@9.39.3) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3))(eslint@9.39.3) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -4622,6 +4735,8 @@ snapshots: semver: 6.3.1 string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.56.1(eslint@9.39.3)(typescript@6.0.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -6045,9 +6160,13 @@ snapshots: dependencies: is-number: 7.0.0 - ts-api-utils@2.4.0(typescript@5.9.3): + ts-api-utils@2.4.0(typescript@6.0.2): dependencies: - typescript: 5.9.3 + typescript: 6.0.2 + + ts-api-utils@2.5.0(typescript@6.0.2): + dependencies: + typescript: 6.0.2 tsconfig-paths@3.15.0: dependencies: @@ -6126,29 +6245,29 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.56.1(eslint@10.0.2)(typescript@5.9.3): + typescript-eslint@8.56.1(eslint@9.39.3)(typescript@6.0.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@10.0.2)(typescript@5.9.3))(eslint@10.0.2)(typescript@5.9.3) - '@typescript-eslint/parser': 8.56.1(eslint@10.0.2)(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@10.0.2)(typescript@5.9.3) - eslint: 10.0.2 - typescript: 5.9.3 + '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3)(typescript@6.0.2) + '@typescript-eslint/parser': 8.56.1(eslint@9.39.3)(typescript@6.0.2) + '@typescript-eslint/typescript-estree': 8.56.1(typescript@6.0.2) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.3)(typescript@6.0.2) + eslint: 9.39.3 + typescript: 6.0.2 transitivePeerDependencies: - supports-color - typescript-eslint@8.56.1(eslint@9.39.3)(typescript@5.9.3): + typescript-eslint@8.58.1(eslint@10.0.2)(typescript@6.0.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@5.9.3))(eslint@9.39.3)(typescript@5.9.3) - '@typescript-eslint/parser': 8.56.1(eslint@9.39.3)(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@9.39.3)(typescript@5.9.3) - eslint: 9.39.3 - typescript: 5.9.3 + '@typescript-eslint/eslint-plugin': 8.58.1(@typescript-eslint/parser@8.58.1(eslint@10.0.2)(typescript@6.0.2))(eslint@10.0.2)(typescript@6.0.2) + '@typescript-eslint/parser': 8.58.1(eslint@10.0.2)(typescript@6.0.2) + '@typescript-eslint/typescript-estree': 8.58.1(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.1(eslint@10.0.2)(typescript@6.0.2) + eslint: 10.0.2 + typescript: 6.0.2 transitivePeerDependencies: - supports-color - typescript@5.9.3: {} + typescript@6.0.2: {} unbox-primitive@1.1.0: dependencies: From c8352c10967ef525f16a29b335ce87ffb8b08c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 18:23:46 +0200 Subject: [PATCH 04/25] chore: bump MUI ^7 -> ^9 - @mui/material and @mui/material-nextjs to ^9 - v9 peers Next 16; pairs with v16-appRouter path fix --- packages/create-next-stack/src/main/plugins/material-ui.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/create-next-stack/src/main/plugins/material-ui.ts b/packages/create-next-stack/src/main/plugins/material-ui.ts index ee86dd9..be9af57 100644 --- a/packages/create-next-stack/src/main/plugins/material-ui.ts +++ b/packages/create-next-stack/src/main/plugins/material-ui.ts @@ -39,8 +39,8 @@ export const materialUIPlugin: Plugin = { description: "Adds support for Material UI", active: ({ flags }) => Boolean(flags["material-ui"]), dependencies: [ - { name: "@mui/material", version: "^7.0.0" }, - { name: "@mui/material-nextjs", version: "^7.0.0" }, + { name: "@mui/material", version: "^9.0.0" }, + { name: "@mui/material-nextjs", version: "^9.0.0" }, { name: "@emotion/cache", version: "^11.0.0" }, ], technologies: [ From 7b5d1fb008fabb9aaa2934399f5dcc7a456bc533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 18:24:50 +0200 Subject: [PATCH 05/25] chore: bump mantine ^8 -> ^9 - plugin: @mantine/core + @mantine/hooks to ^9 - website: same bump --- apps/website/package.json | 4 +- .../src/main/plugins/mantine.ts | 4 +- pnpm-lock.yaml | 168 ++++++------------ 3 files changed, 58 insertions(+), 118 deletions(-) diff --git a/apps/website/package.json b/apps/website/package.json index 125befb..45efe4e 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -12,8 +12,8 @@ "lint": "eslint" }, "dependencies": { - "@mantine/core": "^8.0.0", - "@mantine/hooks": "^8.0.0", + "@mantine/core": "^9.0.0", + "@mantine/hooks": "^9.0.0", "next": "^16.0.0", "next-plausible": "^3.12.0", "react": "^19.0.0", diff --git a/packages/create-next-stack/src/main/plugins/mantine.ts b/packages/create-next-stack/src/main/plugins/mantine.ts index 52adefd..53d8085 100644 --- a/packages/create-next-stack/src/main/plugins/mantine.ts +++ b/packages/create-next-stack/src/main/plugins/mantine.ts @@ -7,8 +7,8 @@ export const mantinePlugin: Plugin = { description: "Adds support for Mantine", active: ({ flags }) => Boolean(flags.mantine), dependencies: [ - { name: "@mantine/core", version: "^8.0.0" }, - { name: "@mantine/hooks", version: "^8.0.0" }, + { name: "@mantine/core", version: "^9.0.0" }, + { name: "@mantine/hooks", version: "^9.0.0" }, ], devDependencies: [ { name: "postcss", version: "^8.0.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1b9712a..4391799 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,11 +27,11 @@ importers: apps/website: dependencies: '@mantine/core': - specifier: ^8.0.0 - version: 8.3.15(@mantine/hooks@8.3.15(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^9.0.0 + version: 9.0.1(@mantine/hooks@9.0.1(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@mantine/hooks': - specifier: ^8.0.0 - version: 8.3.15(react@19.2.4) + specifier: ^9.0.0 + version: 9.0.1(react@19.2.4) next: specifier: ^16.0.0 version: 16.1.6(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -203,10 +203,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/runtime@7.28.6': - resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} - engines: {node: '>=6.9.0'} - '@babel/template@7.28.6': resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} @@ -442,26 +438,26 @@ packages: resolution: {integrity: sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@floating-ui/core@1.7.4': - resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==} + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} - '@floating-ui/dom@1.7.5': - resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==} + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} - '@floating-ui/react-dom@2.1.7': - resolution: {integrity: sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg==} + '@floating-ui/react-dom@2.1.8': + resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' - '@floating-ui/react@0.27.18': - resolution: {integrity: sha512-xJWJxvmy3a05j643gQt+pRbht5XnTlGpsEsAPnMi5F5YTOEEJymA90uZKBD8OvIv5XvZ1qi4GcccSlqT3Bq44Q==} + '@floating-ui/react@0.27.19': + resolution: {integrity: sha512-31B8h5mm8YxotlE7/AU/PhNAl8eWxAmjL/v2QOxroDNkTFLk3Uu82u63N3b6TXa4EGJeeZLVcd/9AlNlVqzeog==} peerDependencies: react: '>=17.0.0' react-dom: '>=17.0.0' - '@floating-ui/utils@0.2.10': - resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} @@ -665,17 +661,17 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@mantine/core@8.3.15': - resolution: {integrity: sha512-wBn/GogB4x7a2Uj7Ztt3amRaApjED+9XqfE4wyCLh88R7KV55k9vnTdCx+irI/GLOOu9tXNUGm3a4t5sTajwkQ==} + '@mantine/core@9.0.1': + resolution: {integrity: sha512-kSYm8g7p8FTDysOsz9BN14TSqp10O0yAmo9HOZfwe6c08gGKQSytnSCPgnTe2h5DMfpbhTg+krROrT8WQy37fA==} peerDependencies: - '@mantine/hooks': 8.3.15 - react: ^18.x || ^19.x - react-dom: ^18.x || ^19.x + '@mantine/hooks': 9.0.1 + react: ^19.2.0 + react-dom: ^19.2.0 - '@mantine/hooks@8.3.15': - resolution: {integrity: sha512-AUSnpUlzttHzJht3CJ1YWi16iy6NWRwtyWO5RLGHHsmiW05DyG0qOPKF8+R5dLHuOCnl3XOu4roI2Y1ku9U04Q==} + '@mantine/hooks@9.0.1': + resolution: {integrity: sha512-WM/GbSD8MxZoy3X2IdrbxLq0/0ca4zMA5m7lGw9k1Vecqt1dC/nBed0IJd/w2HGs6avGs9CPlvQ8C4yBEcSnLA==} peerDependencies: - react: ^18.x || ^19.x + react: ^19.2.0 '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} @@ -2564,8 +2560,8 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-number-format@5.4.4: - resolution: {integrity: sha512-wOmoNZoOpvMminhifQYiYSTCLUDOiUbBunrMrMjA+dV52sY+vck1S4UhR6PkgnoCquvvMSeJjErXZ4qSaWCliA==} + react-number-format@5.4.5: + resolution: {integrity: sha512-y8O2yHHj3w0aE9XO8d2BCcUOOdQTRSVq+WIuMlLVucAm5XNjJAy+BoOJiuQMldVYVOKTMyvVNfnbl2Oqp+YxGw==} peerDependencies: react: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -2600,12 +2596,6 @@ packages: '@types/react': optional: true - react-textarea-autosize@8.5.9: - resolution: {integrity: sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==} - engines: {node: '>=10'} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react@19.2.4: resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} @@ -2878,6 +2868,10 @@ packages: tabbable@6.4.0: resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -2957,9 +2951,9 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} + type-fest@5.5.0: + resolution: {integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==} + engines: {node: '>=20'} typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} @@ -3029,33 +3023,6 @@ packages: '@types/react': optional: true - use-composed-ref@1.4.0: - resolution: {integrity: sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - use-isomorphic-layout-effect@1.2.1: - resolution: {integrity: sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - use-latest@1.3.0: - resolution: {integrity: sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - use-sidecar@1.1.3: resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} engines: {node: '>=10'} @@ -3315,8 +3282,6 @@ snapshots: dependencies: '@babel/types': 7.29.0 - '@babel/runtime@7.28.6': {} - '@babel/template@7.28.6': dependencies: '@babel/code-frame': 7.29.0 @@ -3508,30 +3473,30 @@ snapshots: '@eslint/core': 1.1.0 levn: 0.4.1 - '@floating-ui/core@1.7.4': + '@floating-ui/core@1.7.5': dependencies: - '@floating-ui/utils': 0.2.10 + '@floating-ui/utils': 0.2.11 - '@floating-ui/dom@1.7.5': + '@floating-ui/dom@1.7.6': dependencies: - '@floating-ui/core': 1.7.4 - '@floating-ui/utils': 0.2.10 + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 - '@floating-ui/react-dom@2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@floating-ui/react-dom@2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@floating-ui/dom': 1.7.5 + '@floating-ui/dom': 1.7.6 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@floating-ui/react@0.27.18(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@floating-ui/react@0.27.19(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@floating-ui/react-dom': 2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@floating-ui/utils': 0.2.10 + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@floating-ui/utils': 0.2.11 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) tabbable: 6.4.0 - '@floating-ui/utils@0.2.10': {} + '@floating-ui/utils@0.2.11': {} '@humanfs/core@0.19.1': {} @@ -3678,21 +3643,20 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@mantine/core@8.3.15(@mantine/hooks@8.3.15(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@mantine/core@9.0.1(@mantine/hooks@9.0.1(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@floating-ui/react': 0.27.18(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@mantine/hooks': 8.3.15(react@19.2.4) + '@floating-ui/react': 0.27.19(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@mantine/hooks': 9.0.1(react@19.2.4) clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - react-number-format: 5.4.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-number-format: 5.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) - react-textarea-autosize: 8.5.9(@types/react@19.2.14)(react@19.2.4) - type-fest: 4.41.0 + type-fest: 5.5.0 transitivePeerDependencies: - '@types/react' - '@mantine/hooks@8.3.15(react@19.2.4)': + '@mantine/hooks@9.0.1(react@19.2.4)': dependencies: react: 19.2.4 @@ -5734,7 +5698,7 @@ snapshots: react-is@16.13.1: {} - react-number-format@5.4.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + react-number-format@5.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -5766,15 +5730,6 @@ snapshots: optionalDependencies: '@types/react': 19.2.14 - react-textarea-autosize@8.5.9(@types/react@19.2.14)(react@19.2.4): - dependencies: - '@babel/runtime': 7.28.6 - react: 19.2.4 - use-composed-ref: 1.4.0(@types/react@19.2.14)(react@19.2.4) - use-latest: 1.3.0(@types/react@19.2.14)(react@19.2.4) - transitivePeerDependencies: - - '@types/react' - react@19.2.4: {} readable-stream@3.6.2: @@ -6145,6 +6100,8 @@ snapshots: tabbable@6.4.0: {} + tagged-tag@1.0.0: {} + tinybench@2.9.0: {} tinyexec@1.0.2: {} @@ -6210,7 +6167,9 @@ snapshots: type-fest@0.21.3: {} - type-fest@4.41.0: {} + type-fest@5.5.0: + dependencies: + tagged-tag: 1.0.0 typed-array-buffer@1.0.3: dependencies: @@ -6321,25 +6280,6 @@ snapshots: optionalDependencies: '@types/react': 19.2.14 - use-composed-ref@1.4.0(@types/react@19.2.14)(react@19.2.4): - dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - use-isomorphic-layout-effect@1.2.1(@types/react@19.2.14)(react@19.2.4): - dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - use-latest@1.3.0(@types/react@19.2.14)(react@19.2.4): - dependencies: - react: 19.2.4 - use-isomorphic-layout-effect: 1.2.1(@types/react@19.2.14)(react@19.2.4) - optionalDependencies: - '@types/react': 19.2.14 - use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.4): dependencies: detect-node-es: 1.1.0 From 5e8bf8a716312dba902da823915635cbd50add48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 18:25:04 +0200 Subject: [PATCH 06/25] chore: bump vercel CLI ^50 -> ^51 - ^50.0.0 resolves to [50, 51) and excludes v51 --- packages/create-next-stack/src/main/plugins/vercel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-next-stack/src/main/plugins/vercel.ts b/packages/create-next-stack/src/main/plugins/vercel.ts index ac9f037..5fbe36d 100644 --- a/packages/create-next-stack/src/main/plugins/vercel.ts +++ b/packages/create-next-stack/src/main/plugins/vercel.ts @@ -5,7 +5,7 @@ export const vercelPlugin: Plugin = { name: "Vercel", description: "Adds support for Vercel", active: ({ flags }) => Boolean(flags["vercel"]), - devDependencies: [{ name: "vercel", version: "^50.0.0" }], + devDependencies: [{ name: "vercel", version: "^51.0.0" }], scripts: [ { name: "deploy:vercel", From a4cda4366c88c42c85e235d620b7b1caffa94d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 18:25:17 +0200 Subject: [PATCH 07/25] chore: bump netlify-cli ^24 -> ^25 --- packages/create-next-stack/src/main/plugins/netlify.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-next-stack/src/main/plugins/netlify.ts b/packages/create-next-stack/src/main/plugins/netlify.ts index 8f296f5..f3485cd 100644 --- a/packages/create-next-stack/src/main/plugins/netlify.ts +++ b/packages/create-next-stack/src/main/plugins/netlify.ts @@ -5,7 +5,7 @@ export const netlifyPlugin: Plugin = { name: "Netlify", description: "Adds support for Netlify", active: ({ flags }) => Boolean(flags["netlify"]), - devDependencies: [{ name: "netlify-cli", version: "^24.0.0" }], + devDependencies: [{ name: "netlify-cli", version: "^25.0.0" }], scripts: [ { name: "deploy:netlify", From 981673efa819ba926e5c13115b2c861cc9728099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 18:25:51 +0200 Subject: [PATCH 08/25] chore: bump GH Actions versions - actions/checkout @v4 -> @v6 - actions/setup-node @v4 -> @v6 - pnpm/action-setup @v4 -> @v5 - repo workflows + plugin template for generated projects --- .github/workflows/ci.yml | 6 +++--- .github/workflows/cli-e2e.yml | 12 ++++++------ .github/workflows/publish.yml | 6 +++--- .../src/main/plugins/github-actions.ts | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85299d6..8adaf78 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,13 +14,13 @@ jobs: steps: - name: "Checkout repo" - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: "Set up pnpm" - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v5 - name: "Set up latest Node LTS" - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: "lts/*" cache: pnpm diff --git a/.github/workflows/cli-e2e.yml b/.github/workflows/cli-e2e.yml index 1e994ab..00d24bc 100644 --- a/.github/workflows/cli-e2e.yml +++ b/.github/workflows/cli-e2e.yml @@ -13,13 +13,13 @@ jobs: steps: - name: "Checkout repo" - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: "Set up pnpm" - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v5 - name: "Set up latest Node LTS" - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: "lts/*" cache: pnpm @@ -56,13 +56,13 @@ jobs: steps: - name: "Checkout repo" - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: "Set up pnpm" - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v5 - name: "Set up latest Node LTS" - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: "lts/*" cache: pnpm diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a323ca9..cc647f9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,13 +20,13 @@ jobs: steps: - name: "Checkout repo" - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: "Set up pnpm" - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v5 - name: "Set up latest Node LTS" - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: "lts/*" registry-url: "https://registry.npmjs.org" diff --git a/packages/create-next-stack/src/main/plugins/github-actions.ts b/packages/create-next-stack/src/main/plugins/github-actions.ts index 00051fe..258422c 100644 --- a/packages/create-next-stack/src/main/plugins/github-actions.ts +++ b/packages/create-next-stack/src/main/plugins/github-actions.ts @@ -66,19 +66,19 @@ const generateCiYml = async (inputs: ValidCNSInputs): Promise => { steps: - name: "Checkout repo" - uses: actions/checkout@v4 + uses: actions/checkout@v6 ${ packageManager === "pnpm" ? aldent` - name: "Set up pnpm" - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v5 ` : "" } - name: "Set up latest Node LTS" - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: "lts/*" cache: "${packageManager}" From eae3e12927b8e5ef68120ca987481ca1d6294533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 20:34:53 +0200 Subject: [PATCH 09/25] fix: force light color scheme - replace defaultColorScheme -> forceColorScheme on ColorSchemeScript + MantineProvider - site has no dark mode styling; ignore localStorage/system preference --- apps/website/app/layout.tsx | 2 +- apps/website/app/providers.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/website/app/layout.tsx b/apps/website/app/layout.tsx index d9cd05f..f482159 100644 --- a/apps/website/app/layout.tsx +++ b/apps/website/app/layout.tsx @@ -29,7 +29,7 @@ export default function RootLayout({ return ( - + + {children} ) From 00df11e29118cd9c4f4f8136139d73b9e42d2981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 20:35:14 +0200 Subject: [PATCH 10/25] fix: inherit color on social icon links - add style color:inherit to wrappers - prevent default browser blue/purple link colors on icons --- apps/website/components/SocialIcons.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/website/components/SocialIcons.tsx b/apps/website/components/SocialIcons.tsx index 8144918..33c8029 100644 --- a/apps/website/components/SocialIcons.tsx +++ b/apps/website/components/SocialIcons.tsx @@ -13,15 +13,21 @@ export const SocialIcons: FC = (props) => { - + From d6def3f7959b523c90897bac54c9f5b2625dd6b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 20:39:02 +0200 Subject: [PATCH 11/25] chore: gitignore next-env.d.ts - auto-generated on next dev/build, flip-flops between versions - per Next.js docs recommendation --- .gitignore | 1 + apps/website/next-env.d.ts | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 apps/website/next-env.d.ts diff --git a/.gitignore b/.gitignore index 20ec8a7..5646e75 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ # next.js **/.next/ **/out/ +**/next-env.d.ts # production **/build diff --git a/apps/website/next-env.d.ts b/apps/website/next-env.d.ts deleted file mode 100644 index 7a70f65..0000000 --- a/apps/website/next-env.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/// -/// -import "./.next/types/routes.d.ts" - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. From a2ae1a885a2d38f55e8bfb15cf48a567f777d151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 20:58:19 +0200 Subject: [PATCH 12/25] refactor: inherit Anchor props from MantineAnchor - use PolymorphicComponentProps<"a", MantineAnchorProps> - drops hand-rolled prop list --- apps/website/components/Anchor.tsx | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/apps/website/components/Anchor.tsx b/apps/website/components/Anchor.tsx index e8750aa..6cefe6a 100644 --- a/apps/website/components/Anchor.tsx +++ b/apps/website/components/Anchor.tsx @@ -1,16 +1,12 @@ "use client" -import { Anchor as MantineAnchor } from "@mantine/core" -import { ReactNode } from "react" - -type AnchorProps = { - href?: string - target?: string - children?: ReactNode - c?: string - fw?: string | number -} +import { + Anchor as MantineAnchor, + AnchorProps as MantineAnchorProps, + PolymorphicComponentProps, +} from "@mantine/core" +type AnchorProps = PolymorphicComponentProps<"a", MantineAnchorProps> export const Anchor = ({ c = "#319bff", fw = "bold", From 03595dcce6c43bbd18c413e2f65b08f65ba842fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 21:09:11 +0200 Subject: [PATCH 13/25] refactor: simplify Anchor wrapper - inline defaults in JSX, drop destructure --- apps/website/components/Anchor.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/website/components/Anchor.tsx b/apps/website/components/Anchor.tsx index 6cefe6a..8dd4d42 100644 --- a/apps/website/components/Anchor.tsx +++ b/apps/website/components/Anchor.tsx @@ -7,10 +7,6 @@ import { } from "@mantine/core" type AnchorProps = PolymorphicComponentProps<"a", MantineAnchorProps> -export const Anchor = ({ - c = "#319bff", - fw = "bold", - ...props -}: AnchorProps) => { - return +export const Anchor = (props: AnchorProps) => { + return } From 660f72a645d5944843a84114795be20532e705e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 21:09:28 +0200 Subject: [PATCH 14/25] chore: add typecheck scripts - tsc --noEmit per package - turbo typecheck + :cli/:web filters at root --- apps/website/package.json | 3 ++- package.json | 3 +++ packages/create-next-stack/package.json | 1 + turbo.json | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/website/package.json b/apps/website/package.json index 45efe4e..27d97c9 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -9,7 +9,8 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "eslint" + "lint": "eslint", + "typecheck": "tsc --noEmit" }, "dependencies": { "@mantine/core": "^9.0.0", diff --git a/package.json b/package.json index 2640cb5..090d616 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,9 @@ "lint": "turbo lint", "lint:cli": "turbo lint --filter create-next-stack", "lint:web": "turbo lint --filter create-next-stack-website", + "typecheck": "turbo typecheck", + "typecheck:cli": "turbo typecheck --filter create-next-stack", + "typecheck:web": "turbo typecheck --filter create-next-stack-website", "test": "turbo test", "test:cli": "turbo test --filter create-next-stack", "test:web": "turbo test --filter create-next-stack-website", diff --git a/packages/create-next-stack/package.json b/packages/create-next-stack/package.json index 685e06e..8a18f09 100644 --- a/packages/create-next-stack/package.json +++ b/packages/create-next-stack/package.json @@ -53,6 +53,7 @@ "build": "rimraf lib && tsc --build", "build:watch": "rimraf lib && tsc --build --watch", "lint": "eslint", + "typecheck": "tsc --noEmit", "test": "pnpm unit", "unit": "vitest run src/main/", "unit:watch": "vitest src/main/", diff --git a/turbo.json b/turbo.json index a083423..9b42344 100644 --- a/turbo.json +++ b/turbo.json @@ -10,6 +10,7 @@ "inputs": ["**/*.ts", "**/*.js", "**/*.tsx", "**/*.jsx"] }, "lint": {}, + "typecheck": {}, "update-readme": { "dependsOn": ["build"], "inputs": ["**/*.ts", "**/*.js", "**/*.tsx", "**/*.jsx"] From 35345a2f1c9443543abd9f057e59be91864845d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 21:40:00 +0200 Subject: [PATCH 15/25] refactor: make Section polymorphic via polymorphic() - drop Box wrapper + as prop in favor of component prop - Mantine's recommended pattern - update Header/Footer to pass component= --- apps/website/components/Section.tsx | 34 ++++++++++--------- .../LandingPage/components/Footer.tsx | 2 +- .../LandingPage/components/Header.tsx | 2 +- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/apps/website/components/Section.tsx b/apps/website/components/Section.tsx index 14bcfa2..6f12132 100644 --- a/apps/website/components/Section.tsx +++ b/apps/website/components/Section.tsx @@ -1,20 +1,22 @@ -import { Box, Flex, FlexProps } from "@mantine/core" -import { FC, ReactNode } from "react" +import { Flex, FlexProps, polymorphic } from "@mantine/core" +import { ReactNode } from "react" -type SectionProps = Omit & { +type SectionProps = FlexProps & { innerProps?: FlexProps children?: ReactNode - as?: "section" | "header" | "footer" } -export const Section: FC = ({ - innerProps, - children, - as: Element = "section", - ...props -}) => { - return ( - - + +export const Section = polymorphic<"section", SectionProps>( + ({ innerProps, children, ...props }: SectionProps) => { + return ( + = ({ {children} - - ) -} + ) + }, +) diff --git a/apps/website/templates/LandingPage/components/Footer.tsx b/apps/website/templates/LandingPage/components/Footer.tsx index 3c897c1..bdc0b0b 100644 --- a/apps/website/templates/LandingPage/components/Footer.tsx +++ b/apps/website/templates/LandingPage/components/Footer.tsx @@ -7,7 +7,7 @@ import { SocialIcons } from "../../../components/SocialIcons" export const Footer: React.FC = () => { return (
{ return ( -
+
Date: Sat, 18 Apr 2026 21:40:14 +0200 Subject: [PATCH 16/25] refactor: make Anchor polymorphic via polymorphic() - Mantine's recommended pattern - drops PolymorphicComponentProps type helper in favor of wrapper --- apps/website/components/Anchor.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/website/components/Anchor.tsx b/apps/website/components/Anchor.tsx index 8dd4d42..e1a3927 100644 --- a/apps/website/components/Anchor.tsx +++ b/apps/website/components/Anchor.tsx @@ -3,10 +3,11 @@ import { Anchor as MantineAnchor, AnchorProps as MantineAnchorProps, - PolymorphicComponentProps, + polymorphic, } from "@mantine/core" -type AnchorProps = PolymorphicComponentProps<"a", MantineAnchorProps> -export const Anchor = (props: AnchorProps) => { - return -} +export const Anchor = polymorphic<"a", MantineAnchorProps>( + (props: MantineAnchorProps) => { + return + }, +) From 1914906b6a9a7da0b37bf835d193ae05fb412980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 21:49:08 +0200 Subject: [PATCH 17/25] refactor: drop FC usage - prefer typed param over FC generic - aligns Checkbox/Radio/Section/SocialIcons/Card/CommandModal/InfoIconTooltip --- apps/website/components/Checkbox.tsx | 5 ++--- apps/website/components/Radio.tsx | 3 +-- apps/website/components/Section.tsx | 3 --- apps/website/components/SocialIcons.tsx | 3 +-- .../website/templates/LandingPage/LandingPageTemplate.tsx | 4 ++-- .../templates/LandingPage/components/CommandModal.tsx | 6 +++--- .../templates/LandingPage/components/InfoIconTooltip.tsx | 8 ++++---- 7 files changed, 13 insertions(+), 19 deletions(-) diff --git a/apps/website/components/Checkbox.tsx b/apps/website/components/Checkbox.tsx index 9b5b32c..17691fd 100644 --- a/apps/website/components/Checkbox.tsx +++ b/apps/website/components/Checkbox.tsx @@ -1,8 +1,7 @@ "use client" -import { Checkbox as MantineCheckbox, CheckboxProps } from "@mantine/core" -import { FC } from "react" +import { CheckboxProps, Checkbox as MantineCheckbox } from "@mantine/core" -export const Checkbox: FC = (props) => { +export const Checkbox = (props: CheckboxProps) => { return } diff --git a/apps/website/components/Radio.tsx b/apps/website/components/Radio.tsx index d92c4d2..8fb97e6 100644 --- a/apps/website/components/Radio.tsx +++ b/apps/website/components/Radio.tsx @@ -1,8 +1,7 @@ "use client" import { Radio as MantineRadio, RadioProps } from "@mantine/core" -import { FC } from "react" -export const Radio: FC = (props) => { +export const Radio = (props: RadioProps) => { return } diff --git a/apps/website/components/Section.tsx b/apps/website/components/Section.tsx index 6f12132..5d11bc6 100644 --- a/apps/website/components/Section.tsx +++ b/apps/website/components/Section.tsx @@ -1,11 +1,8 @@ import { Flex, FlexProps, polymorphic } from "@mantine/core" -import { ReactNode } from "react" type SectionProps = FlexProps & { innerProps?: FlexProps - children?: ReactNode } - export const Section = polymorphic<"section", SectionProps>( ({ innerProps, children, ...props }: SectionProps) => { return ( diff --git a/apps/website/components/SocialIcons.tsx b/apps/website/components/SocialIcons.tsx index 33c8029..eb229fc 100644 --- a/apps/website/components/SocialIcons.tsx +++ b/apps/website/components/SocialIcons.tsx @@ -1,8 +1,7 @@ import { Flex, FlexProps } from "@mantine/core" -import { FC } from "react" import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa" -export const SocialIcons: FC = (props) => { +export const SocialIcons = (props: FlexProps) => { return ( = ({ children }) => ( +const Card = ({ children }: PropsWithChildren) => ( void } -export const CommandModal: FC = ({ +export const CommandModal = ({ command, opened, onClose, -}) => { +}: CommandModalProps) => { const [hasCopied, setHasCopied] = useState(false) const [copyFailed, setCopyFailed] = useState(false) diff --git a/apps/website/templates/LandingPage/components/InfoIconTooltip.tsx b/apps/website/templates/LandingPage/components/InfoIconTooltip.tsx index 3ab985d..ee13582 100644 --- a/apps/website/templates/LandingPage/components/InfoIconTooltip.tsx +++ b/apps/website/templates/LandingPage/components/InfoIconTooltip.tsx @@ -1,17 +1,17 @@ "use client" import { Flex, Tooltip } from "@mantine/core" -import { FC } from "react" +import { ReactNode } from "react" import { FiInfo } from "react-icons/fi" type WithInfoIconAndTooltipProps = { tooltip: string - children: React.ReactNode + children: ReactNode } -export const WithInfoIconAndTooltip: FC = ({ +export const WithInfoIconAndTooltip = ({ tooltip, children, -}) => { +}: WithInfoIconAndTooltipProps) => { return ( From 01d7575cc6c84140cdf17a11855d79f1ce647fea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 22:10:40 +0200 Subject: [PATCH 18/25] refactor: drop redundant use client from CommandModal - already inside client boundary via TechnologiesForm - silences spurious ts(71007) on onClose prop --- apps/website/templates/LandingPage/components/CommandModal.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/website/templates/LandingPage/components/CommandModal.tsx b/apps/website/templates/LandingPage/components/CommandModal.tsx index faf879a..e25414a 100644 --- a/apps/website/templates/LandingPage/components/CommandModal.tsx +++ b/apps/website/templates/LandingPage/components/CommandModal.tsx @@ -1,5 +1,3 @@ -"use client" - import { Button, Code, Flex, Modal, Text } from "@mantine/core" import { useState } from "react" import { FiCheck } from "react-icons/fi" From b0969402c145613ea816c68eb031eb8f1975da90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 22:26:36 +0200 Subject: [PATCH 19/25] refactor: centralize brand gradient via defaultGradient - move gradient to theme.defaultGradient - drop inline gradient props in Header (inherits from theme) --- apps/website/templates/LandingPage/components/Header.tsx | 2 -- apps/website/theme.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/website/templates/LandingPage/components/Header.tsx b/apps/website/templates/LandingPage/components/Header.tsx index 6c5b1b3..bf21815 100644 --- a/apps/website/templates/LandingPage/components/Header.tsx +++ b/apps/website/templates/LandingPage/components/Header.tsx @@ -21,7 +21,6 @@ export const HeaderSection = () => { fw={800} ta={{ base: "left", sm: "center" }} variant="gradient" - gradient={{ from: "#6838F1", to: "#DC51F2", deg: 135 }} lh={1.2} > Create Next Stack @@ -31,7 +30,6 @@ export const HeaderSection = () => { fw="bold" ta={{ base: "left", sm: "center" }} variant="gradient" - gradient={{ from: "#6838F1", to: "#DC51F2", deg: 135 }} > The ultimate starter kit for Next.js diff --git a/apps/website/theme.ts b/apps/website/theme.ts index 435008f..6d95d3d 100644 --- a/apps/website/theme.ts +++ b/apps/website/theme.ts @@ -8,8 +8,8 @@ export const theme = createTheme({ headings: { fontFamily: '"Inter", sans-serif', }, + defaultGradient: { from: "#6838F1", to: "#DC51F2", deg: 135 }, other: { fontFamilyMono: '"Roboto Mono", monospace', - brandGradient: { from: "#6838F1", to: "#DC51F2", deg: 135 }, }, }) From dae822a09d7090ae945b3cdbe129dd569aa3e23b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 22:53:15 +0200 Subject: [PATCH 20/25] refactor: anchor info tooltip on icon, trigger on row - Tooltip target=iconRef positions on icon only - controlled opened via row mouseenter/leave keeps text hover trigger --- .../components/InfoIconTooltip.tsx | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/apps/website/templates/LandingPage/components/InfoIconTooltip.tsx b/apps/website/templates/LandingPage/components/InfoIconTooltip.tsx index ee13582..675a289 100644 --- a/apps/website/templates/LandingPage/components/InfoIconTooltip.tsx +++ b/apps/website/templates/LandingPage/components/InfoIconTooltip.tsx @@ -1,7 +1,7 @@ "use client" import { Flex, Tooltip } from "@mantine/core" -import { ReactNode } from "react" +import { ReactNode, useRef, useState } from "react" import { FiInfo } from "react-icons/fi" type WithInfoIconAndTooltipProps = { @@ -12,12 +12,28 @@ export const WithInfoIconAndTooltip = ({ tooltip, children, }: WithInfoIconAndTooltipProps) => { + const iconRef = useRef(null) + const [opened, setOpened] = useState(false) return ( - - - {children} + setOpened(true)} + onMouseLeave={() => setOpened(false)} + > + {children} + - - + + + ) } From 162321b0da2be29d5bca5f5e88fae8a06c3642cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 18 Apr 2026 23:35:10 +0200 Subject: [PATCH 21/25] refactor: pin generated command to current CLI version - import version from CLI package.json at build time - replaces @latest: deterministic per deploy, still auto-bumps w/ monorepo --- .../templates/LandingPage/components/TechnologiesForm.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/website/templates/LandingPage/components/TechnologiesForm.tsx b/apps/website/templates/LandingPage/components/TechnologiesForm.tsx index 8b21dbc..bf172cd 100644 --- a/apps/website/templates/LandingPage/components/TechnologiesForm.tsx +++ b/apps/website/templates/LandingPage/components/TechnologiesForm.tsx @@ -11,6 +11,7 @@ import { } from "@mantine/core" import React from "react" import { Controller, SubmitHandler, useForm } from "react-hook-form" +import cnsPackageJson from "../../../../../packages/create-next-stack/package.json" import { Anchor } from "../../../components/Anchor" import { Checkbox } from "../../../components/Checkbox" import { Radio } from "../../../components/Radio" @@ -267,7 +268,7 @@ export const TechnologiesForm: React.FC = () => { formData, ) => { const calculateCommand = (formData: TechnologiesFormData) => { - const args = ["npx", "create-next-stack@latest"] + const args = ["npx", `create-next-stack@${cnsPackageJson.version}`] args.push(`--router=${formData.router}`) args.push(`--package-manager=${options[formData.packageManager].value}`) From b94dbb45cad655c7dbceca785fb426f5179ce4b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sun, 19 Apr 2026 00:08:12 +0200 Subject: [PATCH 22/25] fix: restore a11y on invalid checkbox options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add error, aria-invalid, aria-describedby to Checkbox - render error text with stable id for screen reader association - restores parity lost in Chakra→Mantine migration (FormControl isInvalid) --- .../components/TechnologiesForm.tsx | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/apps/website/templates/LandingPage/components/TechnologiesForm.tsx b/apps/website/templates/LandingPage/components/TechnologiesForm.tsx index bf172cd..83973e8 100644 --- a/apps/website/templates/LandingPage/components/TechnologiesForm.tsx +++ b/apps/website/templates/LandingPage/components/TechnologiesForm.tsx @@ -335,24 +335,27 @@ export const TechnologiesForm: React.FC = () => { {optionKeys.map((optionKey) => { + const invalidValidators = + validators?.[optionKey]?.filter((v) => v.isInvalid) ?? [] + const hasError = invalidValidators.length > 0 + const errorId = `${name}-${optionKey}-error` return (
- {validators?.[optionKey]?.map( - (validator) => - validator.isInvalid && ( - + {hasError && ( + + {invalidValidators.map((validator) => ( + {validator.errorMessage} - ), + ))} + )}
) From c106565f2cca37dcaaa2943244f32b0f32f10f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sun, 19 Apr 2026 00:49:05 +0200 Subject: [PATCH 23/25] refactor: replace inline validator w/ validate-npm-package-name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - restore Node builtin-module check (dropped in 78b9068b) - v7 is zero-dep + bundler-safe; prior bundle issue was older version - eliminates website↔CLI validator skew --- apps/website/package.json | 4 +- apps/website/utils/validateProjectName.ts | 72 ++--------------------- pnpm-lock.yaml | 28 ++++++--- 3 files changed, 27 insertions(+), 77 deletions(-) diff --git a/apps/website/package.json b/apps/website/package.json index 27d97c9..a8d25ea 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -20,11 +20,13 @@ "react": "^19.0.0", "react-dom": "^19.0.0", "react-hook-form": "^7.54.0", - "react-icons": "^5.4.0" + "react-icons": "^5.4.0", + "validate-npm-package-name": "^7.0.2" }, "devDependencies": { "@types/node": "^25.0.0", "@types/react": "^19.0.0", + "@types/validate-npm-package-name": "^4.0.2", "eslint": "^9.0.0", "eslint-config-next": "^16.0.0", "eslint-config-prettier": "^10.0.0", diff --git a/apps/website/utils/validateProjectName.ts b/apps/website/utils/validateProjectName.ts index a9a19a1..b9ba57a 100644 --- a/apps/website/utils/validateProjectName.ts +++ b/apps/website/utils/validateProjectName.ts @@ -1,3 +1,5 @@ +import validateNpmPackageName from "validate-npm-package-name" + /** * Project names must be valid npm package names. This function checks that validity. * @@ -5,72 +7,6 @@ * @returns `true` if valid. If invalid, an error message of type `string` explaining the invalidity. */ export const validateProjectName = (projectName: string): string | true => { - const problems = getProblemsInProjectName(projectName) - return problems[0] ?? true -} - -const scopedPackagePattern = /^(?:@([^/]+?)[/])?([^/]+?)$/ -const blacklist = ["node_modules", "favicon.ico"] - -const getProblemsInProjectName = (name: string): string[] => { - const problems: string[] = [] - - if (name.length === 0) { - problems.push("Name must not be empty.") - return problems - } - - if (name.startsWith(".")) { - problems.push("Name must not start with a period.") - } - - if (name.startsWith("_")) { - problems.push("Name must not start with an underscore.") - } - - if (name.trimStart() !== name) { - problems.push("Name must not contain leading spaces.") - } - - if (name.trimEnd() !== name) { - problems.push("Name must not contain trailing spaces.") - } - - if (name.length > 214) { - problems.push("Name must be 214 characters or fewer.") - } - - if (name.toLowerCase() !== name) { - problems.push("Name must not contain uppercase letters.") - } - - if (/[~'!()*]/.test(name.split("/").slice(-1)[0] ?? "")) { - problems.push("Name must not contain special characters (~'!()*)") - } - - if (encodeURIComponent(name) !== name) { - const match = scopedPackagePattern.exec(name) - if (match) { - const user = match[1] - const pkg = match[2] - if ( - user && - pkg && - encodeURIComponent(user) === user && - encodeURIComponent(pkg) === pkg - ) { - // Scoped package name is valid - } else { - problems.push("Name can only contain URL-friendly characters.") - } - } else { - problems.push("Name can only contain URL-friendly characters.") - } - } - - if (blacklist.includes(name)) { - problems.push(`${name} is a reserved name.`) - } - - return problems + const { errors, warnings } = validateNpmPackageName(projectName) + return [...(errors ?? []), ...(warnings ?? [])][0] ?? true } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4391799..4aef0ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,6 +50,9 @@ importers: react-icons: specifier: ^5.4.0 version: 5.5.0(react@19.2.4) + validate-npm-package-name: + specifier: ^7.0.2 + version: 7.0.2 devDependencies: '@types/node': specifier: ^25.0.0 @@ -57,6 +60,9 @@ importers: '@types/react': specifier: ^19.0.0 version: 19.2.14 + '@types/validate-npm-package-name': + specifier: ^4.0.2 + version: 4.0.2 eslint: specifier: ^9.0.0 version: 9.39.3 @@ -3044,6 +3050,10 @@ packages: resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + validate-npm-package-name@7.0.2: + resolution: {integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==} + engines: {node: ^20.17.0 || >=22.9.0} + vite@7.3.1: resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -4620,8 +4630,8 @@ snapshots: '@next/eslint-plugin-next': 16.1.6 eslint: 9.39.3 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3))(eslint@9.39.3) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.3) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.3) eslint-plugin-react: 7.37.5(eslint@9.39.3) eslint-plugin-react-hooks: 7.0.1(eslint@9.39.3) @@ -4651,7 +4661,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.3): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3(supports-color@8.1.1) @@ -4662,22 +4672,22 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3))(eslint@9.39.3) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3))(eslint@9.39.3): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.56.1(eslint@9.39.3)(typescript@6.0.2) eslint: 9.39.3 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.3) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3))(eslint@9.39.3): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -4688,7 +4698,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.3 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint@9.39.3))(eslint@9.39.3))(eslint@9.39.3) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3)(typescript@6.0.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -6294,6 +6304,8 @@ snapshots: validate-npm-package-name@5.0.1: {} + validate-npm-package-name@7.0.2: {} + vite@7.3.1(@types/node@25.3.3)(sugarss@5.0.1(postcss@8.5.6))(yaml@2.8.2): dependencies: esbuild: 0.27.3 From c8d5a2b3f62ceb80e5e28051781a80fe47daae8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sun, 19 Apr 2026 01:05:35 +0200 Subject: [PATCH 24/25] chore: tighten website tsconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - target es2017→ES2022 - add verbatimModuleSyntax, noUncheckedIndexedAccess, noPropertyAccessFromIndexSignature - convert type-only imports (verbatimModuleSyntax) - process.env bracket notation (noPropertyAccessFromIndexSignature) --- apps/website/components/Anchor.tsx | 7 ++----- apps/website/components/Checkbox.tsx | 3 ++- apps/website/components/Radio.tsx | 3 ++- apps/website/components/Section.tsx | 3 ++- apps/website/components/SocialIcons.tsx | 3 ++- .../templates/LandingPage/LandingPageTemplate.tsx | 2 +- .../LandingPage/components/InfoIconTooltip.tsx | 3 ++- .../LandingPage/components/NewsletterSection.tsx | 10 ++++++---- .../LandingPage/components/TechnologiesForm.tsx | 3 ++- apps/website/tsconfig.json | 9 ++++++--- 10 files changed, 27 insertions(+), 19 deletions(-) diff --git a/apps/website/components/Anchor.tsx b/apps/website/components/Anchor.tsx index e1a3927..3121e5f 100644 --- a/apps/website/components/Anchor.tsx +++ b/apps/website/components/Anchor.tsx @@ -1,10 +1,7 @@ "use client" -import { - Anchor as MantineAnchor, - AnchorProps as MantineAnchorProps, - polymorphic, -} from "@mantine/core" +import { Anchor as MantineAnchor, polymorphic } from "@mantine/core" +import type { AnchorProps as MantineAnchorProps } from "@mantine/core" export const Anchor = polymorphic<"a", MantineAnchorProps>( (props: MantineAnchorProps) => { diff --git a/apps/website/components/Checkbox.tsx b/apps/website/components/Checkbox.tsx index 17691fd..56d2f09 100644 --- a/apps/website/components/Checkbox.tsx +++ b/apps/website/components/Checkbox.tsx @@ -1,6 +1,7 @@ "use client" -import { CheckboxProps, Checkbox as MantineCheckbox } from "@mantine/core" +import { Checkbox as MantineCheckbox } from "@mantine/core" +import type { CheckboxProps } from "@mantine/core" export const Checkbox = (props: CheckboxProps) => { return diff --git a/apps/website/components/Radio.tsx b/apps/website/components/Radio.tsx index 8fb97e6..d22ca06 100644 --- a/apps/website/components/Radio.tsx +++ b/apps/website/components/Radio.tsx @@ -1,6 +1,7 @@ "use client" -import { Radio as MantineRadio, RadioProps } from "@mantine/core" +import { Radio as MantineRadio } from "@mantine/core" +import type { RadioProps } from "@mantine/core" export const Radio = (props: RadioProps) => { return diff --git a/apps/website/components/Section.tsx b/apps/website/components/Section.tsx index 5d11bc6..fa845cc 100644 --- a/apps/website/components/Section.tsx +++ b/apps/website/components/Section.tsx @@ -1,4 +1,5 @@ -import { Flex, FlexProps, polymorphic } from "@mantine/core" +import { Flex, polymorphic } from "@mantine/core" +import type { FlexProps } from "@mantine/core" type SectionProps = FlexProps & { innerProps?: FlexProps diff --git a/apps/website/components/SocialIcons.tsx b/apps/website/components/SocialIcons.tsx index eb229fc..fbaee0f 100644 --- a/apps/website/components/SocialIcons.tsx +++ b/apps/website/components/SocialIcons.tsx @@ -1,4 +1,5 @@ -import { Flex, FlexProps } from "@mantine/core" +import { Flex } from "@mantine/core" +import type { FlexProps } from "@mantine/core" import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa" export const SocialIcons = (props: FlexProps) => { diff --git a/apps/website/templates/LandingPage/LandingPageTemplate.tsx b/apps/website/templates/LandingPage/LandingPageTemplate.tsx index 34f3671..b34aade 100644 --- a/apps/website/templates/LandingPage/LandingPageTemplate.tsx +++ b/apps/website/templates/LandingPage/LandingPageTemplate.tsx @@ -1,7 +1,7 @@ "use client" import { Box, Flex } from "@mantine/core" -import { PropsWithChildren } from "react" +import type { PropsWithChildren } from "react" import { Section } from "../../components/Section" import { Description } from "./components/Description" import { Footer } from "./components/Footer" diff --git a/apps/website/templates/LandingPage/components/InfoIconTooltip.tsx b/apps/website/templates/LandingPage/components/InfoIconTooltip.tsx index 675a289..08ff2c9 100644 --- a/apps/website/templates/LandingPage/components/InfoIconTooltip.tsx +++ b/apps/website/templates/LandingPage/components/InfoIconTooltip.tsx @@ -1,7 +1,8 @@ "use client" import { Flex, Tooltip } from "@mantine/core" -import { ReactNode, useRef, useState } from "react" +import { useRef, useState } from "react" +import type { ReactNode } from "react" import { FiInfo } from "react-icons/fi" type WithInfoIconAndTooltipProps = { diff --git a/apps/website/templates/LandingPage/components/NewsletterSection.tsx b/apps/website/templates/LandingPage/components/NewsletterSection.tsx index 2396348..51a45ab 100644 --- a/apps/website/templates/LandingPage/components/NewsletterSection.tsx +++ b/apps/website/templates/LandingPage/components/NewsletterSection.tsx @@ -1,16 +1,18 @@ "use client" import { Button, Flex, Text, TextInput, Title } from "@mantine/core" -import { FC, useState } from "react" -import { SubmitHandler, useForm } from "react-hook-form" +import { useState } from "react" +import type { FC } from "react" +import { useForm } from "react-hook-form" +import type { SubmitHandler } from "react-hook-form" const NEXT_PUBLIC_CONVERTKIT_API_KEY = - process.env.NEXT_PUBLIC_CONVERTKIT_API_KEY + process.env["NEXT_PUBLIC_CONVERTKIT_API_KEY"] if (!NEXT_PUBLIC_CONVERTKIT_API_KEY) { throw new Error("Missing NEXT_PUBLIC_CONVERTKIT_API_KEY environment variable") } const NEXT_PUBLIC_CONVERTKIT_FORM_ID = - process.env.NEXT_PUBLIC_CONVERTKIT_FORM_ID + process.env["NEXT_PUBLIC_CONVERTKIT_FORM_ID"] if (!NEXT_PUBLIC_CONVERTKIT_FORM_ID) { throw new Error("Missing NEXT_PUBLIC_CONVERTKIT_FORM_ID environment variable") } diff --git a/apps/website/templates/LandingPage/components/TechnologiesForm.tsx b/apps/website/templates/LandingPage/components/TechnologiesForm.tsx index 83973e8..143a35b 100644 --- a/apps/website/templates/LandingPage/components/TechnologiesForm.tsx +++ b/apps/website/templates/LandingPage/components/TechnologiesForm.tsx @@ -10,7 +10,8 @@ import { Title, } from "@mantine/core" import React from "react" -import { Controller, SubmitHandler, useForm } from "react-hook-form" +import { Controller, useForm } from "react-hook-form" +import type { SubmitHandler } from "react-hook-form" import cnsPackageJson from "../../../../../packages/create-next-stack/package.json" import { Anchor } from "../../../components/Anchor" import { Checkbox } from "../../../components/Checkbox" diff --git a/apps/website/tsconfig.json b/apps/website/tsconfig.json index d20b9a8..7afaf3b 100644 --- a/apps/website/tsconfig.json +++ b/apps/website/tsconfig.json @@ -1,19 +1,22 @@ { "compilerOptions": { - "target": "es2017", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, - "strict": true, "forceConsistentCasingInFileNames": true, "noEmit": true, "esModuleInterop": true, - "module": "esnext", "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "react-jsx", "incremental": true, + "verbatimModuleSyntax": true, + "noUncheckedIndexedAccess": true, + "noPropertyAccessFromIndexSignature": true, + "target": "ES2022", + "strict": true, + "module": "esnext", "plugins": [ { "name": "next" From 9d755b0893a3526045ff2e9b4d4f3d6530205f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sun, 19 Apr 2026 01:16:45 +0200 Subject: [PATCH 25/25] refactor: log real fs path for URL cwd in runCommand - URL.toString() was producing misleading file:// in debug log - narrow string|URL and fileURLToPath the URL branch --- packages/create-next-stack/src/main/helpers/run-command.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/create-next-stack/src/main/helpers/run-command.ts b/packages/create-next-stack/src/main/helpers/run-command.ts index e51a755..a26db11 100644 --- a/packages/create-next-stack/src/main/helpers/run-command.ts +++ b/packages/create-next-stack/src/main/helpers/run-command.ts @@ -1,4 +1,5 @@ import { execa, type Options, type ResultPromise } from "execa" +import { fileURLToPath } from "url" import { logDebug } from "../logging.ts" import { prettyCommand } from "./pretty-command.ts" @@ -8,6 +9,10 @@ export const runCommand = ( options?: Options, ): ResultPromise => { logDebug("Running command:", prettyCommand(file, args)) - logDebug("Running command in:", options?.cwd?.toString() ?? process.cwd()) + const cwd = options?.cwd ?? process.cwd() + logDebug( + "Running command in:", + typeof cwd === "string" ? cwd : fileURLToPath(cwd), + ) return execa(file, args, options) }