MAX guide 13 min read

How to Automate Framework and Version Upgrades with Moderne, Codemod, and Amazon Q in 2026

Three-engine code migration pipeline routing JVM, JavaScript, and Java version upgrades into automated AST recipes.
Before you dive in

This article is a specific deep-dive within our broader topic of AI Code Migration.

This article assumes familiarity with:

TL;DR

  • Migration is a routing problem first: match each codebase to the engine built for its stack, then run a recipe — don’t hand-edit.
  • The contract is everything. Source version, target version, build tool, and dependency policy must be specified before any tool touches a file.
  • In 2026, all three engines expose MCP, so a coding agent can trigger the upgrade, produce a reviewable diff, and stop before CI.

It’s Monday. The Spring Boot 2.7 end-of-life notice is sitting in your inbox, and hundreds of files in your repo still call deprecated APIs. Your last attempt to upgrade by hand stalled at the third merge conflict and ate a full sprint. You don’t have a coding problem here. You have a specification problem — nobody told the machine exactly what “upgraded” means.

Before You Start

You’ll need:

  • An AI coding tool that speaks Model Context Protocol — Claude Code, Cursor, or Codex
  • A working grasp of how Abstract Syntax Tree rewrites differ from text find-and-replace
  • A clear source-and-target version pair (the thing you’re upgrading from and to)
  • The right migration engine for your stack — we’ll pick it in Step 1

This guide teaches you: how to treat AI Code Migration as a routing-and-contract problem so an automated engine does the rewrite and you just review the diff.

The Six-Month Upgrade That Should Have Taken a Week

Here’s the failure mode I see in every legacy shop. A team decides to “let the AI upgrade the codebase,” opens a chat window, and feeds it files one at a time. It works for the first few. Then a rewrite quietly changes a date parser’s behavior, and nobody can tell which of the hundreds of edits broke the test suite.

It built on Friday. On Monday it broke — because a free-text rewrite bumped a dependency an unrelated module relied on, and nothing in the prompt said “don’t touch the transitive graph.”

That’s the difference between generating code and transforming it. A migration is not a creative writing task. It is a deterministic operation on the structure of your code, and structure is what a chat prompt discards.

Step 1: Route Each Codebase to the Right Engine

Before you specify anything, decide which engine owns the job. There is no single best tool — there are three, each built for a different layer, and routing wrong is the costliest day-one mistake.

Your stack maps to one of three engines:

  • OpenRewrite + Moderne — the JVM-centric standard. OpenRewrite is an open-source recipe engine (Apache License 2.0, maintained by Moderne) that rewrites code by parsing it into a lossless AST, applying a recipe, and printing it back. Moderne is the commercial platform that runs those recipes across many repos at once. Strongest for Java, Spring, Maven, and Gradle.
  • Codemod — JS/TS-first but polyglot, with a community registry and a unified CLI. Its built-in engine is ast-grep (jssg), and it also drives jscodeshift, YAML ast-grep, shell steps, and AI-driven steps. Strongest for frontend and Node framework migrations like React and Next.js.
  • Amazon Q Code Transformation — IDE-driven Java and .NET upgrades, one project at a time, where you already work. No separate platform to stand up.

The Architect’s Rule: If you can’t name which engine owns a repo before you start, the migration has no owner — and an unowned migration drifts.

The tell is your build file. A pom.xml or build.gradle full of Spring points to OpenRewrite. A package.json with a React major-version bump points to Codemod. A Maven project you simply want lifted from Java 8 to a supported runtime, without leaving your IDE, points to Amazon Q.

Step 2: Lock Down the Migration Contract

This is where most migrations are won or lost: specify everything — the engine assumes nothing.

Context checklist — fill every line before running:

  • Source and target versions, explicit. Amazon Q Code Transformation upgrades Java 8, 11, or 17 to either Java 17 or Java 21, and can do library upgrades on a project already at 21 (Amazon Q Developer Docs). “Make it modern” is not a target.
  • Build tool and its version. Amazon Q Code Transformation is Maven-only, needs Maven 3.8 or later, and the project must build in under 55 minutes before it will run (Amazon Q Developer Docs). OpenRewrite runs on both Maven and Gradle.
  • The exact recipe or transformation ID. For Spring Boot, the recipe is org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5, supplied by the rewrite-spring artifact at version 6.31.0 (OpenRewrite Docs). Pin it.
  • Dependency policy. Amazon Q accepts an optional YAML dependency upgrade file where you separate FIRST_PARTY from THIRD_PARTY libraries and set a targetVersion for each (Amazon Q Developer Docs). Decide this before, not during.
  • Out-of-scope list. Formatting, unrelated modules, public API signatures — write down what the engine must not touch.

The Spec Test: If your contract doesn’t pin the recipe version and the dependency policy, the engine will pick defaults — and a default dependency bump is how an “isolated” upgrade reaches into a module you never meant to change.

Compatibility notes:

  • Amazon Q Code Transformation is GA, not preview, and targets Java 17 and 21. The original AWS announcement blog still carries “(preview)” in its title — ignore it. Java-17-only assumptions are outdated.
  • Spring Boot 4.0 recipe is Community Edition and chains the 3.5 recipe as a precursor. Upgrade to 3.5 first as the stable step, then attempt 4.0 (OpenRewrite Docs).
  • The old codemod-com/codemod-registry GitHub repo is deprecated. Recipes now live in the codemod/codemod monorepo and the hosted registry at app.codemod.com/registry. Skip any stale install or publish instructions that point at the old repo.

Step 3: Sequence the Run — Recipe, Diff, Then CI

Order matters: review the diff before CI, never after.

Build order:

  1. Run the engine on an isolated branch first — a migration diff you haven’t read is just a faster way to ship a regression. For OpenRewrite, that’s mvn rewrite:run -Drewrite.activeRecipes=... or gradle rewriteRun (OpenRewrite Docs). For Codemod, it’s npx codemod, which auto-refreshes to the latest CLI (Codemod Docs). For Amazon Q, you start the transformation from JetBrains (which works on modules) or VS Code (which works on projects and workspaces).
  2. Produce one reviewable diff per module — a single giant diff across the whole repo is unreviewable, and unreviewed is unshipped.
  3. Gate on CI last — the pipeline is the judge, not the author.

The 2026 difference is the connective layer. Codemod installs a skill and an MCP server with npx codemod ai, wiring into Claude, Cursor, Goose, OpenCode, and Codex (Codemod Docs). The Amazon Q and AWS ecosystem exposes MCP the same way, so a coding agent can drive the whole sequence — trigger the recipe, surface the diff, pause for your review — instead of you running commands by hand.

Keep one distinction straight. Amazon Q Code Transformation is the per-project, in-IDE tool; AWS Transform custom is a separate agentic, org-scale service whose automated codebase-analysis transformation reached GA in March 2026 (AWS What’s New). Reach for the agentic service when you’re modernizing across an organization, not a single repo.

Step 4: Prove the Migration Is Safe

A green build is necessary, not sufficient. You’re verifying that behavior is preserved, not just that the code compiles.

Validation checklist:

  • The project still builds inside the engine’s window — failure looks like: Amazon Q rejecting the project because it exceeds the 55-minute build ceiling. Trim the build before you migrate, not after.
  • Tests pass with no new skips — failure looks like: a suddenly “passing” suite where three integration tests were silently marked ignored during the rewrite.
  • The diff contains no manual TODOs or unresolved markers — failure looks like: the engine leaving a comment where it couldn’t safely transform, which you then merge without noticing.
  • Every changed file maps to a recipe — failure looks like: an edit you can’t attribute to any recipe, which means something off-spec touched your code.
Three-engine code migration pipeline: route by stack, lock the contract, run on a branch, then gate on CI
The four-step pipeline: route the codebase to OpenRewrite, Codemod, or Amazon Q, lock the version contract, run on an isolated branch, then validate before CI.

Common Pitfalls

What You DidWhy AI FailedThe Fix
Pasted files into a chat window one by oneFree-text generation discards code structure; behavioral drift accumulates silentlyUse an AST-based engine that transforms structure deterministically
Said “upgrade to the latest”No pinned target version; the engine picked a default you didn’t wantName the exact source and target version in the contract
Ran Amazon Q on a Gradle projectAmazon Q Code Transformation is Maven-onlyRoute Gradle JVM upgrades to OpenRewrite instead
Jumped straight to Spring Boot 4.0The 4.0 recipe chains 3.5 as a precursor; skipping it breaks the chainUpgrade to 3.5 first, then run the 4.0 recipe
Let the engine commit to the CI branchNo human read the diff before the pipeline didRun on an isolated branch, review per-module diffs, then gate on CI

Pro Tip

Treat the recipe ID and version as part of your source of truth, not a runtime guess. Pin rewrite-spring to a specific version and reference the plugin as the 6.x series rather than chasing a -SNAPSHOT development build — a SNAPSHOT can change under you between two runs, and a migration that isn’t reproducible isn’t a migration, it’s a gamble. The same discipline applies to every engine: the version you ran with is as important as the version you upgraded to.

Frequently Asked Questions

Q: How to set up an AI code migration pipeline step by step in 2026? A: Assess each repo, route it to the engine that matches the stack, run the recipe on an isolated branch, review the diff, then gate on CI. The 2026 addition: wire the engine through MCP with a step like npx codemod ai so a coding agent triggers and surfaces the migration for you.

Q: How to use Amazon Q Code Transformation to upgrade a Java 8 application to Java 17? A: Open the Maven project in VS Code or a JetBrains IDE, confirm it builds in under 55 minutes, then start the transformation targeting Java 17. Watch for the optional YAML dependency upgrade file — it lets you pin FIRST_PARTY and THIRD_PARTY library versions so the runtime jump doesn’t drag in surprises.

Q: How to use OpenRewrite recipes to upgrade Spring Boot across versions? A: Add the rewrite-spring dependency, activate the UpgradeSpringBoot_3_5 recipe, and run mvn rewrite:run or gradle rewriteRun. The edge case: the Spring Boot 4.0 recipe is Community Edition only and chains the 3.5 recipe first, so land on 3.5 as your stable step before attempting 4.0.

Your Spec Artifact

By the end of this guide, you should have:

  • An engine routing map — each repo tagged with the engine that owns it (OpenRewrite/Moderne, Codemod, or Amazon Q) and the one-line reason why.
  • A migration contract — source version, target version, build tool, pinned recipe ID, and a dependency policy separating first-party from third-party.
  • A validation gate — build-time ceiling, test-skip check, no-stray-TODO check, and a rule that every changed file maps to a recipe.

Your Implementation Prompt

Drop this into your AI coding tool once it has MCP access to your migration engine. It encodes the four steps above. Fill every bracket with your own values — each one maps to a checklist item from Step 2.

You are driving an AI code migration for our repository. Follow this spec exactly.

# 1. Route (assess)
- Primary language/runtime: [Java 8 / Java 11 / TypeScript+React / .NET]
- Build tool and version: [Maven 3.8+ / Gradle / npm]
- Migration engine to use: [Amazon Q Code Transformation / OpenRewrite via Moderne / Codemod]
- Why this engine fits: [JVM AST recipes / JS-TS ast-grep / in-IDE Java upgrade]

# 2. Lock the contract (specify)
- Source version: [e.g., Java 8]
- Target version: [e.g., Java 17 or 21]
- Recipe / transformation ID: [e.g., org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5]
- Recipe artifact + version: [e.g., rewrite-spring:6.31.0]
- Dependency policy: [FIRST_PARTY targetVersion=... ; THIRD_PARTY targetVersion=...]
- Out of scope — do NOT change: [formatting, unrelated modules, public API signatures]

# 3. Sequence (build)
1. Run the recipe/transformation on a clean, isolated branch.
2. Produce one reviewable diff per module.
3. Stop and report. Do NOT touch CI config until I approve the diff.

# 4. Validate (prove it)
- Project must build in under [55] minutes.
- All existing tests pass with zero new skips or ignores.
- Diff contains no manual TODOs or unresolved markers.
- List every changed file and the recipe that changed it.

A note on budget: Amazon Q Developer Pro is $19 per user per month and includes 4,000 lines of Java upgrade per month, with overage at $0.003 per line (Amazon Q Developer pricing page). Moderne is free for OSS maintainers via the public tenant at app.moderne.io; Standard and Enterprise are contact-sales only. Prices are indicative — check current pricing before you put a cost constraint in your spec.

Ship It

You now have a mental model that holds past a single file: migration is routing plus a contract, not a chat session. Once you can name the engine, pin the recipe, and write the out-of-scope list, the AI stops guessing and starts producing diffs you can actually review — and the next upgrade becomes a checklist instead of a sprint.

Deploy safe, Max.

AI-assisted content, human-reviewed. Images AI-generated. Editorial Standards · Our Editors

Share: