Skip to content

Use Case: Parallel Migration from Vite to Next.js 16

This is a real use case performed with Claude Code + Superpowers. The content below describes the process from brainstorm to completion, including the UI redesign after migration.

Migrating a React application from Vite to Next.js 16 isn't a job for a single agent working sequentially. Superpowers lets you brainstorm strategy, write a detailed plan, and dispatch multiple agents in parallel -- each owning their own files, with no conflicts.


Context

The project is a Todo App with login functionality, built with React 19 + Vite 7. Here's the current stack:

AspectDetails
FrameworkReact 19 + Vite 7 (SPA, no routing)
LanguageTypeScript 5.9 (strict mode)
UITailwind CSS 4 + shadcn/ui
StateContext API + useReducer
BackendNone -- 100% localStorage
AuthClient-side SHA-256 hash, stored in localStorage
FeaturesTodo CRUD, Drag-drop, Filters, Dark mode, Auth
TestingVitest + React Testing Library

Goal: Migrate everything to Next.js 16 App Router, keeping existing logic intact (localStorage, client-side auth, UI libraries). Team has 3-4 agents available to work in parallel.

Key requirements:

  • Only change the framework, don't change logic
  • All existing tests must still pass after migration
  • Multiple agents can work simultaneously on different files

What You'll Learn

After reading this use case, you'll know how to apply Superpowers techniques to a real refactor/migration scenario:

  1. Brainstorming migration strategy -- ask the right questions, propose approaches, and choose the optimal path
  2. Writing Plans for parallel work -- divide tasks by phase with clear dependencies
  3. Parallel Subagents for concurrent execution -- 3 agents working simultaneously on separate files
  4. Two-Stage Code Review to ensure quality -- automatic spec review after each phase
  5. Verification to confirm results -- build + tests must pass before continuing

Step-by-Step Walkthrough

Step 0: Brainstorm the Migration Strategy

Before writing a plan, you need to brainstorm to determine the strategy. You open a chat with AI and say:

"I need to refactor this entire project to NextJS 16. It's a web todo app with account login. The team has 3-4 agents available to work in parallel. Let's brainstorm the refactoring strategy before starting."

AI enters brainstorm mode (using the superpowers:brainstorming skill), explores the codebase, then starts asking questions one at a time:

AI: "What's the scope of this refactor?"

  • A) Full-stack -- Add real database, API routes, server-side authentication
  • B) Hybrid -- Server Components + App Router for rendering, but keep localStorage
  • C) Framework migration only -- Switch from Vite to Next.js 16, keep all existing logic

Choose: C) Framework migration only -- focus on project structure and routing.

AI: "For routing, what URL structure?"

  • A) Minimal routing -- Just 2 routes: / (todo app) and /login (auth page)
  • B) Structured routing -- Multiple routes: /login, /register, /todos, /todos/[id]

Choose: A) Minimal routing -- simple, closest to the current setup.

AI: "Keep or change current UI libraries?"

Choose: Keep everything -- shadcn/ui, @dnd-kit, sonner, date-fns, lucide-react.

AI: "Which testing framework?"

  • A) Keep Vitest -- Next.js 16 supports it natively
  • B) Switch to Jest

Choose: A) Keep Vitest.

AI: "Any specific deployment target?"

  • A) Vercel -- Best optimized for Next.js, zero config
  • B) Self-hosted / Docker
  • C) Not concerned yet -- Focus on migration first

Choose: C) Not concerned yet -- focus on migration first.

After gathering enough information, AI presents 3 approaches:

## Approach A: New Scaffold + Migrate Piece by Piece (Recommended)
Create a new Next.js 16 project, copy/adapt each piece over.
- Pros: Clean structure, easy to divide among parallel agents, project runs from the start
- Cons: Need to reconfigure (shadcn, tailwind)

## Approach B: In-place migration
Convert directly on the current project -- replace Vite with Next.js.
- Pros: Preserves git history
- Cons: Easy to conflict, project won't run mid-migration, hard to divide parallel tasks

## Approach C: Codemods + automation
Use @next/codemod and scripts for automatic conversion.
- Pros: Fast for basic parts
- Cons: Codemods don't cover Vite -> Next.js, overkill for a small project

## Recommendation
Approach A. Small project (~15 components), scaffolding fresh is faster than in-place migration.
Easy to divide among 3-4 parallel agents.

Choose Approach A. AI asks: "Do you want me to display diagrams and mockups in the browser?" -> Agreed. AI launches the visual companion (a local server) to render architecture diagrams directly in the browser.

AI continues presenting the detailed design across 5 sections (displayed in the browser):

  1. Project Structure -- New directory structure with App Router (app/, components/, hooks/, lib/, types/, contexts/)
  2. Component Mapping -- Classify Server vs Client Components. Pattern: Thin Server Shell -> Fat Client Tree
  3. Routing & Auth Flow -- / wrapped in AuthGuard, /login redirects if already logged in, uses next/navigation
  4. Agent Parallelization -- 3 phases: Foundation -> Parallel Features -> Integration
  5. Migration Details -- Packages to add/remove, config changes, import paths

AI saves the design spec to docs/superpowers/specs/ and dispatches an automatic spec reviewer. The reviewer finds 3 issues (missing todo-app.tsx orchestrator, test directory structure, Toaster placement) -> AI fixes them -> reviewer approves on the 2nd round.

Note: The design spec is saved to docs/superpowers/specs/ and reviewed before writing the plan. See Brainstorming for more details.


Step 1: Superpowers Writes a Plan Dividing Tasks

Before any code is written, AI creates a detailed plan (using the superpowers:writing-plans skill). This is the core principle: no plan, no execution.

AI reads all source files, then creates a plan with 10 tasks divided into 3 phases:

Phase 1: Foundation (1 agent, sequential -- must finish first)

  1. Task 1: Scaffold new Next.js 16 project with create-next-app
  2. Task 2: Add dependencies and config (Tailwind, shadcn, Vitest, tsconfig)
  3. Task 3: Copy unchanged files (lib/, types/, hooks/, contexts/, components/ui/)
  4. Task 4: Create app/layout.tsx -- Root layout with AuthProvider and Toaster
  5. Task 5: Create app/globals.css -- Migrate CSS from src/index.css

Phase 2: Features (3 agents in parallel)

  1. Task 6 -- Auth Agent: Create auth pages (auth-guard.tsx, auth-page.tsx, login-form.tsx, register-form.tsx, app/login/page.tsx)
  2. Task 7 -- Todo Agent: Create todo page (todo-app.tsx, header.tsx, filter-bar.tsx, todo-list.tsx, todo-item.tsx, todo-input.tsx, edit-todo-dialog.tsx, app/page.tsx)
  3. Task 8 -- Test Agent: Migrate 8 test files to __tests__/, update relative imports to @/ alias

Phase 3: Integration (1 agent, sequential)

  1. Task 9: Run npm run build + npx vitest run, fix any issues
  2. Task 10: Cleanup and final commit

Dependency graph:

Phase 1 (Tasks 1-5) --- sequential ---> Phase 2 (Tasks 6-8) --- parallel ---> Phase 3 (Tasks 9-10)
                                          |-- Auth Agent (Task 6)
                                          |-- Todo Agent (Task 7)
                                          +-- Test Agent (Task 8)

The prerequisite for parallel execution: each agent owns separate files, no overlap. Auth Agent only modifies auth-related files, Todo Agent only modifies todo-related files, Test Agent only creates test files.

AI dispatches an automatic plan reviewer -> reviewer finds 1 issue (test files using relative imports will break when moved) -> AI fixes with an import mapping table -> reviewer approves.

AI asks about execution method:

"Two execution methods: 1) Subagent-Driven (recommended) -- dispatch agents, review between tasks. 2) Inline Execution -- execute directly in session. Which one?"

Choose: 1) Subagent-Driven -- fits the requirement for 3-4 parallel agents.

Step 2: Phase 1 -- Foundation

AI combines the 5 foundation tasks into 1 large agent (since they depend on each other sequentially). The agent executes:

  1. Scaffold: npx create-next-app@latest with TypeScript, Tailwind CSS, App Router
  2. Config: Add dependencies (@dnd-kit/*, sonner, date-fns, shadcn, etc.), setup vitest.config.ts, components.json
  3. Copy files: lib/, types/, hooks/, contexts/, components/ui/ -- copied as-is, only adding "use client" at the top of files
  4. Layout: Create app/layout.tsx with metadata, fonts, <AuthProvider>, <Toaster />
  5. CSS: Migrate globals.css with Tailwind 4 syntax

After Phase 1 completes (7 commits), AI dispatches a background spec reviewer to check compliance while preparing Phase 2.

Phase 1: DONE -- 7 commits, build successful, all files in place

Step 3: Dispatch 3 Agents in Parallel (Phase 2)

When Phase 1 is done, the controller dispatches 3 agents simultaneously:

AgentTaskFiles Owned
Auth AgentAuth pages + route protectionauth-guard, auth-page, login-form, register-form, app/login/page.tsx
Todo AgentTodo page + all componentstodo-app, header, filter-bar, todo-list, todo-item, todo-input, edit-todo-dialog, app/page.tsx
Test AgentMigrate 8 test files__tests__/components/, __tests__/contexts/, __tests__/hooks/, __tests__/lib/

Each agent receives:

  • Clear scope: specific file list from the plan
  • Spec reference: link to the design spec for component adaptation details
  • Constraint: don't modify files outside scope, add "use client" at the top of every interactive component

How it actually played out:

  • Auth Agent finishes first -- 5 files, TypeScript passes, commit 740e5dd. IDE shows an error in todo-list.tsx importing ./todo-item -- but that's because Todo Agent hasn't finished creating the file yet, it will resolve itself.

  • Todo Agent finishes next -- 8 files, TypeScript passes, commit 55a8988. Creates a new todo-app.tsx as orchestrator (extracted logic from App.tsx), wrapped in <AuthGuard>.

  • Test Agent finishes last -- creates all 8 test files but can't run tests/commit due to missing permissions. Controller runs npx vitest run and commits instead -- 39/39 tests PASS.

Auth Agent: DONE -- 5 files, TypeScript pass
Todo Agent: DONE -- 8 files, TypeScript pass
Test Agent: DONE -- 8 test files migrated, 39/39 tests pass

Step 4: Phase 3 -- Integration Verification

When all 3 agents complete, the controller runs integration:

npm run build

Build fails! Error: window is not defined -- happens because useTheme and useTodos access window/localStorage in useState initializers. This is an SSR prerendering issue specific to Next.js (Vite doesn't have this).

Fix: Add SSR guards to hooks:

// hooks/use-theme.ts
const [theme, setTheme] = useState<'light' | 'dark'>(() => {
  if (typeof window === 'undefined') return 'light' // SSR guard
  const saved = loadTheme()
  if (saved) return saved
  return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
})

// hooks/use-todos.ts
const [todos, dispatch] = useReducer(todoReducer, [], () => {
  if (typeof window === 'undefined') return [] // SSR guard
  return loadTodos()
})

Run again: npm run build -> Build successful! npx vitest run -> 39/39 tests PASS!

Real-world lesson: When migrating from an SPA (Vite) to a framework with SSR (Next.js), always guard browser-only APIs (window, localStorage, document) in initial state. This is the most common issue.

Step 5: Verification Gate

Before declaring the migration complete:

1. RUN

npm run build && npx vitest run

2. READ

 Compiled successfully
Routes:
  /           -- Static
  /login      -- Static
  /_not-found -- Static

Test Suites: 8 passed, 8 total
Tests:       39 passed, 39 total

3. CONFIRM

MetricResult
Buildnext build successful
Tests39/39 pass (8 test files)
Routes/ (todo app), /login (auth)
Commits11 clean commits

4. GIT HISTORY

050db4f chore: add .superpowers/ to .gitignore
edfa697 fix: guard window/localStorage access for SSR prerendering
97542b0 test: migrate all test files to __tests__/ directory
55a8988 feat: add todo page with all components
740e5dd feat: add auth pages with client-side route protection
76abbff fix: add "use client" to sonner component, accept Next.js tsconfig updates
e78ce06 feat: add root layout with AuthProvider and Toaster
65ff090 chore: copy unchanged source files
451ad1d chore: configure TypeScript, Vitest, and shadcn
a50080f chore: add project dependencies
bb0f5c5 chore: scaffold Next.js 16 project

Bonus: Neo Brutalism Redesign (Parallel Follow-Up)

After the migration was complete and verified, the team continued with a new request: redesign the entire UI in Neo Brutalism style. The Superpowers workflow repeats exactly the same way:

Brainstorm Neo Brutalism

AI asks 5 questions:

  1. Level of brutal -> Choose: Bold Neo Brutalism (3px black borders, hard shadows, vivid colors)
  2. Color palette -> Choose: Candy Crush (pink/purple/blue -- #FF85A1, #A855F7, #38BDF8)
  3. Scope -> Choose: Everything (both login and todo pages)
  4. Dark mode -> Choose: Keep both (light Neo Brutalism as primary, dark adapted)
  5. Font -> Choose: Space Grotesk (geometric sans-serif popular in Neo Brutalism)

AI proposes 3 approaches -> Choose CSS-first (change via CSS variables + Tailwind classes, keep component structure intact, tests still pass).

Neo Brutalism Plan: 6 Tasks, 4 Phases

PhaseTasksAgentsDescription
1: FoundationTask 11Font swap, CSS variables, utility classes
2: Base UITask 21button, input, dialog, select, dropdown, popover, sonner, calendar
3: ComponentsTasks 3-53 parallelAuth (A), Layout (B), Items (C)
4: IntegrationTask 61Build, tests, visual check

Parallel Execution

Phase 1+2 (combined into 1 agent since they're sequentially dependent):

  • Swap font from Geist to Space Grotesk
  • Replace all CSS variables (OKLch colors -> Candy Crush palette)
  • Add utility classes: .brutal-shadow, .brutal-border, hover/active transforms
  • Update shadcn/ui base components (button, input, dialog, select...)

Phase 3 -- 3 agents in parallel:

AgentFiles
Agent A: Authauth-page, login-form, register-form
Agent B: Layoutheader, filter-bar, todo-list
Agent C: Itemstodo-item, todo-input, edit-todo-dialog

Phase 4: Build + Test -> 39/39 tests still pass (because only styling changed, logic untouched).

Neo Brutalism Results

  • Font: Geist -> Space Grotesk Variable
  • Colors: OKLch neutral -> Candy Crush (pink/purple/blue)
  • Borders: 1px transparent -> 3px solid black
  • Shadows: Soft blur -> Hard 4px offset (no blur)
  • Hover/Active: Lift up / Push down transforms
  • Dark mode: Navy background, colored borders, bold colors preserved
  • 5 commits for the entire redesign

Overall Results

After completing both migration and redesign:

MetricBeforeAfter
FrameworkReact 19 + Vite 7 (SPA)Next.js 16 App Router
RoutingNone (toggle state)/ and /login with next/navigation
ComponentsAll client-sideServer shells + Client components
StyleDefault shadcn/uiBold Neo Brutalism (Candy Crush)
FontGeistSpace Grotesk
Tests39 pass39 pass (no breakage)
Commits--11 (migration) + 5 (redesign) = 16 commits
  • 0 tests broken -- logic preserved 100%
  • Significant time savings through parallel execution (3 agents for Phase 2 migration + 3 agents for Phase 3 redesign)
  • Real-world issues fixed on-the-fly: SSR window guard, "use client" directive for sonner, test import paths

Key Takeaways

  1. Brainstorm before coding. Asking the right questions (scope, approach, constraints) prevents refactoring in the wrong direction. In this case, 5 brainstorming questions clearly established: "framework migration only, fresh scaffold, keep all logic."

  2. A detailed plan is the prerequisite for parallel execution. The plan must specify: who does what, which files, dependencies between tasks. Without clear file ownership, agents will conflict.

  3. Divide phases by dependency, parallelize within each phase. Foundation must finish first (scaffold, config), then dispatch agents in parallel for features. This is the pattern: Sequential Phases -> Parallel Tasks Within Phase.

  4. Both spec and plan are automatically reviewed. AI dispatches a reviewer agent after writing the spec/plan. The reviewer catches issues (missing orchestrator component, wrong test import paths) before execution begins -- fixing early is far cheaper than fixing after coding.

  5. Real-world issues always surface. In this case, SSR window is not defined is a specific issue when migrating SPA -> SSR framework. The Integration phase (Phase 3) exists to catch and fix these issues.

  6. The process is repeatable. After migration, the Neo Brutalism redesign followed the exact same workflow: brainstorm -> spec -> plan -> parallel execution -> verify. Same pattern, different context.


Summary: Migrate a React/Vite application to Next.js 16 + Neo Brutalism redesign in the same session. Superpowers orchestrates everything: brainstorming determines strategy, the plan divides tasks by phase, parallel agents execute simultaneously, spec review ensures quality, and the verification gate catches issues before declaring completion. Result: 16 commits, 39/39 tests pass, 0 regression.