Migrating a React App to Next.js using Agentic Planning
Hướng dẫn chi tiết về Migrating a React App to Next.js using Agentic Planning trong Vibe Coding dành cho None.
Migrating a React App to Next.js using Agentic Planning
The transition from a standard Create React App (CRA) or Vite-based Single Page Application (SPA) to Next.js is often viewed as a rite of passage for modern web developers. While the benefits—Server-Side Rendering (SSR), Static Site Generation (SSG), and superior Image Optimization—are undeniable, the manual labor involved is notoriously high-friction. You aren’t just changing a framework; you are shifting a paradigm from client-side dominance to a hybrid server-first architecture.
In the world of Vibe Coding, we don’t settle for manual drudgery. Vibe Coding is about high-level intent, strategic orchestration, and leveraging AI agents to handle the “heavy lifting” of code transformation. This article explores how to use Agentic Planning to migrate a React application to Next.js, turning a multi-week technical debt nightmare into a structured, validated, and largely automated workflow.
The Hook: Beyond Manual Refactoring
Imagine a legacy React dashboard. It has fifty components, ten custom hooks, and a complex state management system using Redux or Context API. Migrating this manually involves:
- Setting up the Next.js directory structure.
- Refactoring every route into the
app/router. - Determining which components should be “Client Components” and which should be “Server Components.”
- Translating
useEffectdata fetching into async Server Component calls. - Fixing broken global CSS and image paths.
This is where “Agentic Planning” changes the game. Instead of you performing these steps, you act as the Orchestrator. You employ an AI agent (like the one you are interacting with now) to analyze the codebase, generate a multi-phase migration plan, and execute the refactors while you maintain the “Vibe”—the creative and strategic direction of the project.
Core Concepts: What is Agentic Planning?
1. The Agentic Loop
Agentic planning isn’t just about asking an AI to “convert this file.” It involves a self-correcting loop:
- Research: The agent maps the existing component tree and dependency graph.
- Strategy: The agent identifies architectural bottlenecks (e.g., a library that doesn’t support SSR).
- Execution: The agent applies surgical changes across multiple files.
- Validation: The agent runs build commands, checks for linting errors, and verifies the “Vibe” matches the original intent.
2. Vibe Coding & The “Strangler Pattern”
In Vibe Coding, we often use the Strangler Fig Pattern. We don’t delete the old app and start fresh. Instead, we scaffold a Next.js wrapper and “strangle” the old functionality by migrating it page-by-page. Agentic planning excels here because an agent can maintain the context of both the legacy and the modern codebases simultaneously.
3. Server vs. Client Components (The RSC Shift)
The biggest hurdle in Next.js migration is the React Server Components (RSC) paradigm.
- Server Components: Fetch data directly on the server (no
useEffect, nouseState). - Client Components: Traditional React components marked with
'use client'.
An agentic plan includes a dedicated “Classification Phase” where the AI scans imports and hooks to decide which components must remain on the client and which should move to the server for performance.
The Workflow: A Practical Example
Let’s walk through a real-world scenario: Migrating a React-based E-commerce product page to Next.js.
Phase 1: The Investigation (Research)
Your first directive to the agent should be an Inquiry. You want the agent to understand the “As-Is” state.
Prompt to the Agent:
“Analyze my current
/srcdirectory. Identify all routes, global state dependencies, and data-fetching patterns. Create a map of components that useuseStateoruseEffect.”
The agent will use tools like grep_search and codebase_investigator to find that your ProductCard.tsx fetches data from a REST API inside a useEffect hook. It will note that your NavBar uses a Sticky library that requires the window object.
Phase 2: The Migration Strategy
Now, the agent generates a MIGRATION_PLAN.md. This is the “Planning” part of Agentic Planning.
Example Strategy Output:
- Scaffold: Initialize Next.js with
npx create-next-app@latestusing the--typescriptand--tailwindflags. - Layout Migration: Convert
App.jswrapping logic intoapp/layout.tsx. - Route Mapping: Map
src/pages/ProductPage.jstoapp/products/[id]/page.tsx. - Data Refactoring: Move the
fetchProductlogic from the client to thepage.tsxserver component. - Client Hydration: Mark the
AddToCartbutton as a Client Component because it requires interactivity.
Phase 3: Interactive Execution
This is where the “Act” part of the cycle happens. Instead of writing the code, you issue Directives based on the plan.
Directive:
“Execute step 4 of the plan. Refactor the product fetching logic into the
app/products/[id]/page.tsxas an async server component. Keep the styling consistent with the existing CSS-in-JS.”
Before (Legacy React):
// src/components/ProductPage.js
function ProductPage({ id }) {
const [product, setProduct] = useState(null);
useEffect(() => {
fetch(`/api/products/${id}`).then(res => res.json()).then(setProduct);
}, [id]);
if (!product) return <Loading />;
return <div className="p-4">{product.name}</div>;
}
After (Next.js Agentic Refactor):
// app/products/[id]/page.tsx
import { getProduct } from '@/lib/api';
export default async function Page({ params }: { params: { id: string } }) {
const product = await getProduct(params.id);
return (
<div className="p-4">
<h1>{product.name}</h1>
{/* Interactivity is moved to a client component */}
<AddToCartButton productId={product.id} />
</div>
);
}
Practical Example: Handling the “Sticky” Problem
One of the most common issues in migration is third-party libraries that rely on window. A manual developer might get frustrated with “window is not defined” errors during SSR. An agentic planner anticipates this.
The Strategy:
The agent detects that react-sticky-box is used in the Sidebar. It automatically implements a dynamic import with ssr: false.
Agent Execution Output:
// app/components/Sidebar.tsx
'use client';
import dynamic from 'next/dynamic';
const StickyBox = dynamic(() => import('react-sticky-box'), { ssr: false });
export function Sidebar({ children }) {
return <StickyBox>{children}</StickyBox>;
}
Best Practices & Tips for Agentic Migration
1. Maintain a “Continuity File”
When working with AI agents over several hours, maintain a CONTINUITY.md or use a skill like cm-continuity. This file stores the current progress, known blockers, and decisions made (e.g., “We decided to keep Redux for the cart state for now”).
2. Prompt for “Surgical Changes”
Avoid asking the agent to “migrate the whole app.” Use the Atomic Task approach. Ask for one route at a time. This keeps the context window clean and reduces the chance of hallucinations.
3. Use the “Validation Gate”
Every time an agent modifies a file, your next command should be a validation directive.
“Run
npm run buildand report any TypeScript errors related to the changes inapp/products/.”
4. Leverage “Vibe Checking”
Since Next.js handles images differently, your agent should automatically replace <img> tags with next/image.
“Scan the migrated components and optimize all image tags using
next/image. Ensure layout-shift is minimized by providing width and height attributes based on the existing CSS.”
Solving the Real Problem in Vibe Coding
The core “Vibe Coding” problem is the Technical Wall. A developer has a great “vibe” (a vision for a product), but they hit a wall when faced with a 1,000-line migration. Agentic planning breaks this wall. It allows the creator to stay in the “Creative Flow” while the AI agents act as the technical staff.
By using an agent to plan the migration, you ensure:
- Consistency: The AI won’t forget to add
'use client'to the 15th component. - Best Practices: The AI can be instructed to follow the latest Next.js 15+ patterns, which might be newer than the developer’s manual knowledge.
- Speed: What would take a weekend of debugging takes 30 minutes of “Orchestrating.”
Conclusion: From Coder to Orchestrator
Migrating a React app to Next.js is no longer about manually moving files and fixing imports. With Agentic Planning, it becomes a strategic operation. You define the intent, the agent researches the codebase, proposes a strategy, and executes the transformation with built-in validation.
This shift represents the true essence of Vibe Coding. You aren’t just writing code; you are managing a system of intelligence that understands your architecture as well as you do. The result is a faster, more SEO-friendly, and more performant application, delivered without the traditional “migration fatigue.”
Next Steps for You:
- Audit: Run an “Inquiry” on your current React app using your agent.
- Plan: Ask for a
STRATEGY.mdfor a Next.js migration. - Execute: Start with the
layout.tsxand your simplest route. - Vibe: Enjoy the process of watching your app evolve through intelligent orchestration.