September 24, 2025

Spec-Driven Frontend Migration with AI Prompts

Spec-Driven Frontend Migration with AI Prompts

Most people think AI makes code migration easier. It doesn't. At least not the way most teams are using it. The popular approach is to feed your code to ChatGPT and ask it to convert things. This works for toy projects. It fails spectacularly on real codebases.

Here's why: AI tools treat your code like a pile of isolated files. But real applications aren't piles of files. They're systems. Change one part and you affect five others in ways you didn't expect.

There's a better approach. Instead of prompting AI tools to rewrite individual pieces, you can use AI agents that understand your entire system. The difference is like asking someone to fix your car versus hiring a mechanic who knows how cars work.

Why Everyone's Doing Migration Wrong

Walk into most companies and you'll find engineers copying code into ChatGPT. They explain what they want. The AI spits out new code. They paste it back and hope it works. When it breaks something else, they repeat the process.

This is backwards. You're making the AI figure out your system from scratch every single time. It's like hiring a new electrician for every outlet in your house and explaining your wiring from the beginning each time.

The problem gets worse with scale. A typical enterprise app has 400,000 files spread across dozens of repositories. No AI tool can hold all that context in its "memory." So you end up explaining the same architectural decisions over and over.

Academic research shows that migration projects fail because teams underestimate the interconnectedness of their code. They think they're changing one thing, but they're actually changing a dozen things they can't see.

What you need isn't better prompts. You need AI that already understands your system.

The Tools That Actually Work

Before you can use AI effectively for migration, you need the right foundation. Most teams skip this step and wonder why their results are inconsistent.

jscodeshift is the standard tool for JavaScript transformations. It converts your code into a tree structure that computers can understand and modify systematically:

npm install -g jscodeshift
npx jscodeshift --help

For TypeScript projects, ts-morph provides better control over type definitions and interface changes:

import { Project, StructureKind } from "ts-morph";
const project = new Project();
project.addSourceFilesAtPaths("src/**/*.ts");
const sourceFiles = project.getSourceFiles();

Angular teams should use ng-morph, while Vue developers can try the vue-migration-helper for identifying deprecated patterns.

These tools are good at finding patterns and making systematic changes. But they can't understand what those changes mean for your application. That's where most teams get stuck.

Why Context Beats Tokens

The AI industry is obsessed with context windows. "Look, we can handle 100K tokens!" But bigger context windows don't solve the real problem.

Think about it this way: if you showed someone 100,000 lines of code and asked them to understand how it all fits together, they'd be overwhelmed. More information isn't the same as better understanding.

What you need is AI that has already learned how your specific system works. Not AI that sees more code at once, but AI that understands the patterns and relationships in your code.

ResearchGate research shows that systematic prompting can help with migrations, but it still requires manual context injection for every change.

The smarter approach is to use AI agents that maintain persistent understanding of your codebase. Instead of explaining your architecture repeatedly, the agent already knows how your user service connects to your payment flows and authentication patterns.

How Real Teams Do Migration

GitHub's Spec Kit provides a framework for AI-assisted development, but it's designed for new projects, not legacy migration.

The best documented migration process comes from Airbnb. They migrated 3,500 React test files in six weeks using a systematic approach. InfoQ's analysis shows they treated each file as an independent unit and processed them through a state machine.

ByteByteGo's technical breakdown reveals that Airbnb broke down the migration process into structured steps before applying AI-assisted transformations.

But even Airbnb's approach has limitations. They still had to manually inject context for each file. For teams with complex interdependencies, this approach breaks down.

Frontend Mastery research identifies two strategies that work:

  • Outside In: Start from application boundaries and work inward
  • Inside Out: Replace smaller sections first

The choice depends on how committed you are to the migration. But both approaches fail without proper understanding of how changes affect the rest of your system.

What Good Migration Looks Like

Here's how migration should work: you tell the system what you want to accomplish. It analyzes your entire codebase to understand the implications. It makes all the necessary changes across all affected files. It updates tests and documentation. It creates a pull request with everything you need.

Most teams are doing this manually:

// Traditional approach
const generateMigrationPrompt = (componentCode, dependencies) => {
return `
Convert this React class component to a functional component with hooks:
Component Code:
${componentCode}
Dependencies:
${dependencies.join(', ')}
Requirements:
- Maintain all existing functionality
- Convert lifecycle methods to appropriate hooks
- Preserve TypeScript types
- Add error boundaries where appropriate
`;
};

The problem with this approach is that you're recreating context every time. You have to remember and specify all the constraints and patterns that matter for your specific application.

FireCMS demonstrates a systematic approach to GPT-4-powered automated code migration:

const openai = new OpenAI({
apiKey: "YOUR_API_KEY"
});
const systemInstructions = `You are a tool which only purpose is converting sx props from the emotion library to tailwind classes. If there is no obvious translation, use classes and styles.`;
const getRecursiveFileReads = async (dir: string, onFileRead: (filePath: string, content: string) => void) => {
// Process files systematically
};

This approach demonstrates the importance of specific, focused prompts rather than generic conversion requests. But it still treats each file in isolation.

Integration That Doesn't Fight You

Most AI tools require constant context switching. You copy code out of your editor, paste it into a web interface, explain what you want, copy the result back, and hope it works.

This is exhausting. It's also inefficient. By the time you've explained your requirements and validated the output, you could have made the changes yourself.

Better tools work directly in your development environment. They understand your existing workflow and fit into it rather than forcing you to adapt to them.

GitHub Actions Importer shows what systematic automation looks like:

  • audit: Analyze existing pipeline compatibility
  • forecast: Estimate migration effort and complexity
  • dry-run: Convert pipeline and output YAML without applying changes
  • migrate: Convert pipeline and create pull request with changes

This is the right pattern: analyze, plan, test, execute. Most AI tools skip the analyze and plan steps.

Testing That Prevents Disasters

Migration projects fail when teams discover problems too late. You need testing that validates not just that your code works, but that it works the same way as before.

describe('Component Migration Validation', () => {
test('original and migrated components produce identical output', () => {
const originalOutput = render(<OriginalComponent {...testProps} />);
const migratedOutput = render(<MigratedComponent {...testProps} />);
expect(migratedOutput.container.innerHTML)
.toEqual(originalOutput.container.innerHTML);
});
});

You also need performance testing. Migrations should make your application faster, not slower. Track bundle size, rendering performance, and memory usage to ensure you're moving in the right direction.

The best migration tools generate these tests automatically. They understand what needs to be preserved and create validation that ensures nothing breaks.

Why AI Sometimes Makes Things Worse

Controlled studies show that AI tools slow down experienced developers by 19%. This seems counterintuitive until you think about why.

Experienced developers are fast because they understand the system they're working in. They know which changes are safe and which are risky. They know how different parts of the code relate to each other.

When you use AI tools that don't understand your system, you lose this advantage. You have to explain context that you normally take for granted. You have to validate suggestions that a human expert would immediately recognize as wrong.

GitClear's analysis of 211 million lines of code shows that AI-assisted code has measurably different quality characteristics. The tools aren't just slow, they're producing different kinds of code.

This is why the distinction between prompting tools and understanding tools matters. Tools that understand your system preserve your existing patterns and constraints. Tools that don't understand your system require you to specify everything explicitly.

Measuring Success

Most teams measure migration success wrong. They count lines of code converted or features migrated. But the real question is whether the migration made development easier.

Good metrics for migration success:

  • Build time improvements (40% faster is typical for good migrations)
  • Developer onboarding time (should drop from weeks to days)
  • Context-switching incidents (how often do developers get confused by the codebase?)
  • Breaking changes that require manual fixes (should be under 5%)

Monterail's Vue 3 migration case study documents outcomes including smaller bundle sizes and better performance. But according to Monterail's State of Vue.js Report, 25% of developers still struggle with Vue 2 to Vue 3 migrations.

The difference is usually in the approach. Teams that understand their system architecture succeed. Teams that don't understand their system struggle.

The Real Lesson

The migration problem isn't really about AI. It's about understanding.

Most software systems grow organically. People add features and fix bugs without maintaining a clear picture of how everything fits together. Eventually the system becomes too complex for any individual to understand completely.

This is where good AI tools become valuable. Not because they're smarter than humans, but because they can maintain a consistent understanding of the entire system while humans focus on the parts they care about.

The future isn't AI that replaces human judgment. It's AI that preserves and extends human understanding. Tools that let you work at the level of architectural decisions while handling the mechanical work of updating code across hundreds of files.

Think about it this way: we don't use compilers because they're smarter than us. We use them because they're more reliable at mechanical translation. The same principle applies to migration tools. The best ones handle the mechanical work while preserving the architectural intelligence that humans provide.

But you have to choose tools that understand systems, not just syntax. The difference determines whether your migration takes three weeks or six months.

Molisha Shah

GTM and Customer Champion