Repository navigation
Major maintenance update: App Router support, dependency bumps, website overhaul #271
Copy link
Copy link
Description
The project has been dormant since mid-2023. This issue tracks the full maintenance update to make create-next-stack current and relevant again.
Key decisions
- Support both App Router (default) and Pages Router via
--routerflag - Update all plugin dependencies to latest major versions
- Migrate website from Chakra UI to Mantine, Pages Router to App Router
Phase 0: Build tooling & infrastructure
- TypeScript 4.9 -> 5.x (superseded by Phase 9: now ^6)
- Turbo v1 -> v2 (
pipeline->tasks) - Prettier v2 -> v3
- pnpm v8 -> v10
- Husky v8 -> v9
- oclif v2 -> v4
- Node engines >=18 -> >=20
- GitHub Actions versions (setup-node@v4, checkout@v4, pnpm/action-setup@v4) (superseded by Phase 9: @v6 / @v6 / @v5)
Phase 1: Slot system refactoring + router flag
- Add
--routerflag (app/pages, default app) - Refactor Plugin type: rename
slots.app->slots.pagesApp, addslots.appLayoutfor App Router - App Router
providers.tsxpattern (separate'use client'wrapper component) - New generators:
app/layout.tsx,app/providers.tsx,app/page.tsx - Conditional file generation based on router flag
- Update Next.js plugin:
create-next-app13.2.3 -> 15.x, update CNA flags
Phase 2: Plugin updates
Simple bumps
-
framer-motion->motion^12 (package renamed, imports frommotion/react) - react-icons ^4 -> ^5
- prisma ^4 -> ^6 (v7 too breaking; see Finish Prisma support #270) (Phase 9 re-evaluated v7 — still too breaking; left at ^6)
- vercel ^30 -> ^50, netlify ^15 -> ^24 (superseded by Phase 9: vercel ^51, netlify ^25)
- github-actions template update (checkout@v4, setup-node@v4, pnpm/action-setup@v4) (superseded by Phase 9)
- react-query ^4 -> ^5 + App Router provider slots
- sass, next-plausible, react-hook-form, formik version checks + App Router slots where needed (next-plausible slipped — caught and bumped to ^4 in Phase 9)
Breaking changes
- Tailwind CSS v3 -> v4 (CSS-based config via
@import "tailwindcss", drop tailwind.config.js/autoprefixer, use@tailwindcss/postcss) - Chakra UI v2 -> v3 (still needs
@emotion/react, drops@emotion/styled/framer-motion/@chakra-ui/icons, usescreateSystem/defineConfig, needsnext-themes) - Mantine v6 -> v8 (dropped Emotion, uses PostCSS with
postcss-preset-mantine, CSS imports,createTheme). Hybrid App Router approach: layout slots for CSS import/mantineHtmlProps/ColorSchemeScript, provider slots forMantineProvider(superseded by Phase 9: now ^9) - Material UI v5 -> v7 +
@mui/material-nextjsfor App Router (AppRouterCacheProvider) (superseded by Phase 9: now ^9) - Styled Components v5 -> v6 (built-in TS types, drop
@types/styled-components, add App Router registry viauseServerInsertedHTML) - Emotion: add App Router provider slots (
CacheProvider+useServerInsertedHTML), add README todo about CSS-in-JS Client Component requirement - CSS Modules: App Router layout import (done in Phase 1)
Infrastructure
- Add
postcssConfigslot to Plugin type (likenextConfigslots) for PostCSS plugin merging (Mantine + Tailwind coexistence) - Migrate
next.config.js->next.config.tsgeneration
Formatting/hooks
- Prettier ^2 -> ^3, eslint-config-prettier ^8 -> ^10
- Drop
mrm/mrm-task-lint-staged, use Husky v9 (npx husky init) + lint-staged ^16
Phase 3: Validation rules
- Remove "Mantine requires Emotion" constraint
- Keep "Chakra requires Emotion" (v3 still uses Emotion)
- Remove "Chakra requires Framer Motion" constraint
- Keep "Material UI requires Emotion"
- Update flag descriptions to match (Chakra, Mantine)
Phase 4: E2E tests
- Add
--router=pagestest variants (pages-router-emotion-all-flags, pages-router-tailwind-css-only) - Add
--prismaand--github-actionsto all-flags tests - Add Mantine-without-Emotion test (tailwind-css-with-mantine)
- Remove obsolete invalid-input cases (mantineWithoutEmotion, chakraWithoutFramerMotion)
- Update chakraWithoutEmotion test (remove --framer-motion from args)
Bugs found and fixed during E2E testing
- oclif v4 single-command CLI:
commandsconfig must use{ strategy: "single", target: "..." }format instead of old string path +defaultkey. Without this, flags like--debugwere parsed as command names. - CNA 15 Turbopack prompt:
create-next-app@15now prompts interactively for Turbopack. Added--turbopackflag to prevent hanging. - LandingPageTemplate missing
"use client": Template usesonLoad,localStorage, andwindow-- needs client directive for App Router. - Emotion
jsxImportSourcebreaks App Router: SettingjsxImportSource: "@emotion/react"globally in tsconfig makes Server Components import Emotion's JSX runtime, causingcreateContext is not a function. Fix: only set for Pages Router, use per-file pragma for App Router. - Emotion
cache.insertedtype:EmotionCache.insertedis typed asRecord<string, string | true | undefined>-- noanycast needed. Values oftrueindicate already-inserted styles that should be skipped.
CI fixes (PR #274)
- Vitest 4 CLI changes:
--jsonlists test cases not files (use--filesOnly),--poolOptions.*removed (use--no-fileParallelism) - ESM
require.resolve(): Replace withimport.meta.resolve()+fileURLToPath() - Node type stripping: Add
verbatimModuleSyntax: true, convert 53 files toimport type - Generated import extensions: Use extensionless imports (
.ts/.tsxextensions fail across router configs) - Generated template lint errors: Fix
no-explicit-anyin LandingPage utils - pnpm frozen-lockfile in CI: Use explicit
--no-frozen-lockfileflag (pnpm usesci-infoto detect CI) - Duplicate
ThemeProvider: Alias MUI's toMuiThemeProviderwhen Chakra+MUI coexist - Plausible env var narrowing: Move null check from
providerAfterImportstoproviderLogicfor TS narrowing - pnpm
@types/reactcorruption:auto-install-peersrewrites@types/reactto^6.0.0; fix by adding explicit@types/react@^19devDep - Duplicate imports in generated code: Add
prettier-plugin-organize-importsas tmpDependency to dedupe/sort imports during formatting - Lock file format check failure: Generate
.prettierignore(with prettier plugin) to exclude lock files; E2E creates temp ignore when prettier not selected - Styled-components rules-of-hooks: Extract
StyledComponentsRegistrycomponent so early return doesn't make other plugins' hooks conditional
Phase 5: Website overhaul
- Migrate from Chakra UI to Mantine v8
- Migrate from Pages Router to App Router
- Add Router selector to form
- Update validation rules and command builder
- Bump Next.js 13 -> 15, React 18 -> 19
Phase 6: Next.js 16 / CNA 16 support
- Update
create-next-appfrom v15 to v16, add--yesflag (skips React Compiler prompt) - ESLint:
.eslintrc.json->eslint.config.mjs(flat config, ESLint v9) - Lint script:
next lint->eslint - Prettier ESLint integration: update for flat config compat (
eslint-config-prettier) - Update
removeOfficialCNAContentfor CNA 16 file structure - Fix Prettier formatting in CLI package (35 files reformatted)
- Update E2E
performFinalChecksfor new lint command (already usesnpm run lint) - Update website to Next.js 16
Phase 7: Update internal tooling dependencies
Website
-
ESLint ^9 -> ^10Blocked:eslint-config-next@16plugins don't support ESLint 10 yet - @types/node ^22 -> ^25
CLI internal tooling
- ESLint ^8 -> ^10 + migrate
.eslintrctoeslint.config.mjs(flat config) - @typescript-eslint/* ^7 -> ^8 (replaced with unified
typescript-eslintpackage) - Jest ^29 -> ^30, @jest/globals ^29 -> ^30
- next (devDep) ^15 -> ^16
- @types/node ^20 -> ^25
Phase 8: Migrate CLI to ESM
-
tsconfig.json:module: "nodenext",moduleResolution: "nodenext",rewriteRelativeImportExtensions: true, dropdeclaration: true -
package.json: add"type": "module" -
bin/run+bin/dev: convertrequire()toimport() - Replace
__dirnameusages withimport.meta.dirname - Add
.tsextensions to all relative imports - Bump chalk ^4 -> ^5 (ESM-only), execa ^5 -> ^9 (ESM-only)
- Replace endent with aldent (ESM-native), published aldent 0.0.7 with compiled JS output
- Replace Jest with Vitest (native ESM + .ts import support)
- Verify build, lint, unit tests, and CLI execution
Phase 9: Post-merge review follow-ups (2026-04-18)
Discovered during a post-merge review of #274. PR did what it said, but two bugs slipped through and several "update to latest" todos are now stale after time passed.
Bugs
-
plugins/material-ui.ts:87: import path is@mui/material-nextjs/v15-appRouterbut CNA is pinned to v16 — change to/v16-appRouter(breaks MUI + App Router on Next 16) -
plugins/plausible.ts:11:next-plausiblestill pinned^3.0.0; v4 shipped. Missed during Phase 2a "version checks".
Version currency (missed or released since merge)
- TypeScript ^5 -> ^6
- MUI ^7 -> ^9 (both
@mui/materialand@mui/material-nextjs; resolves the v15→v16 import path above) - Mantine ^8 -> ^9 (plugin + website)
- vercel CLI ^50 -> ^51 (
^50.0.0does NOT cover v51) - netlify-cli ^24 -> ^25
- GH Actions bump (both
.github/workflows/*.ymlANDplugins/github-actions.tstemplate):actions/checkout@v4->@v6actions/setup-node@v4->@v6pnpm/action-setup@v4->@v5
- Revisit Finish Prisma support #270: Prisma v7 is now released — re-evaluate the "too breaking" block. Still too breaking: v7 requires provider rename (
prisma-client-js→prisma-client), mandatoryoutputfield, newprisma.config.ts, driver adapters (e.g.@prisma/adapter-better-sqlite3), import-path changes, removed middleware, disabled env auto-load. Needs a dedicated migration PR — left at ^6.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity