← Blog
Code ModernizationOpenRewriteProduct

Make large-scale code changes that teams can review and trust with Moderne

Contents
  1. Development workflows built for one repository don’t scale to thousands.
  2. How do you keep code consistent across thousands of repositories?
  3. Seven safeguards build trust in large-scale change.
  4. How should a team choose a refactoring tool for cross-repo consistency?
  5. Some changes should be pushed to teams and others pulled by them.
  6. Developers stay in control of every change.
  7. How can AI help with cross-repository refactoring?
  8. Platform teams curate the recipes, and product teams choose when to run them.
  9. Large-scale change becomes routine when the process supports it.

Large-scale code changes are trustworthy when every change comes from a deterministic recipe, every result can be reviewed before it’s committed, and developers decide what merges. Moderne runs that process across thousands of repositories at once, so a fix or migration lands everywhere it’s needed.

Even when the process is sound, change at this scale makes people nervous. We once worked with a large bank whose junior developer (let’s call him Lou) was eager to use Moderne to fix a widespread issue. Lou ran a recipe that made deterministic, rule-based changes across hundreds of repositories and committed them.

When the VP of Engineering saw a wave of commits from someone named “Lou,” they asked the team: “Who is Lou, and why did he change everything?” The changes were sound, the builds passed, and nothing broke. Large-scale change still made people uneasy, even with automation they could trust.

Most teams already know what needs fixing. They lack a way to make one careful change across hundreds of repositories.

Development workflows built for one repository don’t scale to thousands.

Code reviews, CI pipelines, and even organizational policies assume one repository and one team at a time. When a security issue or framework update affects hundreds of services, handing the work out repository by repository is slow and hard to track.

As Will Larson has explained, migrations are often the only way to meaningfully address technical debt, especially when individual teams can’t fix it in isolation. They become more frequent as companies grow, and running them well can become a constraint on engineering velocity. Larson’s playbook has three phases:

  • Derisk: design and validate the migration with the hardest, most edge-case-heavy teams first.

  • Enable: build tools and documentation that automate the easy 90%, so teams can self-serve.

  • Finish: stop new code from using the old system, then push through the long tail to 100% adoption.

Automation has long covered infrastructure configuration and simple version bumps in that playbook, while code changes stayed manual, one developer and one repository at a time. Moderne brings code migrations into it with OpenRewrite recipes, which developers and coding agents can both run. Teams validate a migration recipe on the hardest repositories first, run it to automate the easy majority, and rerun it to push the long tail to completion.

The traditional way: one app, one repo

  • 4 of 125 tasks completed
  • App-by-app, sequential
Category# of tasksPercentage
Completed43.2%
Remaining12196.8%

The Moderne way: horizontal change across the organization

  • 100 of 125 tasks completed
  • Across the whole organization
Category# of tasksPercentage
Completed10080%
Remaining2520%
In a 125-task example, horizontal change reaches most of the estate in the time the traditional path (one app, one repo, one team) covers a fraction.

An OpenRewrite recipe is a deterministic, testable transformation, so it makes the same change in every repository it runs on. Moderne runs it across the whole organization and reports the results in one place.

How do you keep code consistent across thousands of repositories?

Write the change once as a deterministic recipe and run it against every repository from one place. Review the results before anything is committed, then open one pull request per repository, each with the same audit trail.

Seven safeguards build trust in large-scale change.

Moderne builds a check into every step, from how a recipe is tested to how its pull requests are reviewed:

  1. Deterministic, rules-based recipes. A recipe only changes code when it finds a clear, known match for the pattern it targets.

  2. Extensive unit testing. Moderne tests recipes against broad sets of real-world examples, and the test code is often longer than the recipe code.

  3. Validation against open source code. Moderne runs recipes against tens of thousands of open source repositories on Moderne’s public tenant before release.

  4. Compile verification. After a change, the Verify compilation recipe checks that the code still compiles, using the type information in the Lossless Semantic Tree (LST), without a full build of every repository.

  5. CI status in the platform. Build and test results for each pull request show up in Moderne, so developers don’t have to switch tools or chase logs.

  6. Incremental change. Big changes can be broken into smaller, staged or draft pull requests to match developer workflows and release schedules.

  7. Real-world use. Recipes run constantly across open source and enterprise codebases, so edge cases surface and get fixed.

How should a team choose a refactoring tool for cross-repo consistency?

Look for deterministic changes (the same input always gives the same output), type-aware matching instead of text search, results you can review across every repository before committing, and pull requests that leave developers in control of the merge.

Some changes should be pushed to teams and others pulled by them.

Teams using Moderne run both modes from the same recipes. Which one fits depends on how urgent the change is and how much it depends on each team’s context.

  • Push-based changes are small and urgent, like security vulnerability fixes. A central team issues them as pull requests across the organization, and teams expect and accept them with little disruption. Fixing Log4j once took Choice Hotels six weeks of all-hands engineering. The team now opens 200 remediation pull requests in an hour.

  • Pull-based changes are complex and context-sensitive, like framework migrations or large refactors, and are often staged. Developers on product teams drive them, usually with a platform or architecture team leading a cross-team working group. That group prepares and validates the recipes and supports rollout across teams, including code that lacks clear ownership.

Customers describe both modes in practice:

  • Code quality and build tool upgrades: “If our priority is to standardize code quality or upgrade tools like Gradle, we issue PRs through Moderne. These changes are safe, tested, and easily reviewed. We do them at the start of every sprint—just one commit that triggers the pipeline. It’s quick and worth doing every two weeks.”

  • Complex migrations using draft PRs: “For migrations like Spring Boot 2 to 3, we use draft PRs. These don’t trigger CI, so there’s no infra load. Developers pull the draft PR locally, compile, test, and make final changes. When ready, they finalize and merge. It saves time and respects developer flow.”

  • Vulnerable dependencies: “Instead of letting surprise CVEs break the build mid-sprint, we run scans weekly. Fixes are issued as a single commit. It’s less stressful and more strategic. If a critical vulnerability is announced, we can run it on demand.”

Run regularly and visibly, remediation stops being a disruption and becomes part of the development rhythm.

Developers stay in control of every change.

Developers co-author changes with Moderne, whether they run a recipe themselves or hand it to a coding agent, and review every diff before it merges. Source code management permissions mirror existing access controls, so there’s no shadow system. Recipes can be dry-run and tested locally, and Moderne can commit directly, create a branch or fork, or open pull requests, depending on how a team works.

Preparing a change starts with data. Impact analysis shows where the change applies, then refactoring recipes make it, and anything that needs manual attention or cross-team coordination is flagged. Migrating from Java 8 to Java 25, for example, may also require updates to Docker images or build configurations. The same analysis shows which parts of the codebase have automated tests and which need extra regression testing before the change goes out. Coding agents work from the same data: Trigrep finds every place a pattern lives by type and symbol, and Prethink gives the agent each repository’s context before it plans the change. The agent then runs the same recipes a developer would to make it.

Moderne developer-driven multi-repo automation

Integrates with existing developer/SCM workflows.

  • Developer research and impact analysis
  • Migration campaigns with code changes
  • Security vulnerability remediations
  • CI quality gates
  • Develop and test auto-refactoring recipes

* Mass building LSTs to enable multi-repo work is executed through a separate, non-production CI workflow.

TEST/QADEPLOYPLANDEVMULTI-REPO WORKEnterprise CI/CDworkflow

Every diff gets the review a coding assistant’s suggestion would get. The difference is scale: one recipe makes the same reviewed change across thousands of repositories.

That review also keeps floods of failing pull requests out of the pipeline, so teams keep trusting it. One principal developer put it this way: “I’m tired of going around telling my kids to pick up their socks.” With automation, the fix becomes routine.

How can AI help with cross-repository refactoring?

Use the agent to plan the change and a deterministic recipe to make it. An agent editing files directly can make a slightly different edit in each repository. A recipe makes the same one everywhere, and through Moderne, agents like Claude Code and Cursor can run recipes across thousands of repositories.

Platform teams curate the recipes, and product teams choose when to run them.

Moderne gives platform teams a proactive role in code quality and modernization that doesn’t depend on top-down enforcement. Central teams can:

  • Manage the recipe catalog: curate open source recipes, write internal ones, and test them for safety and style.

  • Align recipes with security and compliance goals, then publish them across the organization, so developers always have trusted recipes to use.

  • Advise on larger transformations like Java 25 migrations, logging standardization, or right-sizing cloud configurations, helping product teams scope multi-repo change.

  • Launch change campaigns in DevCenter, so developers run remediations when the timing fits and platform teams can see adoption repository by repository.

  • Track every change with Changelog, which follows pull requests and commits across repositories and source control systems, organized the way the company is.

  • Lead on urgent issues like critical vulnerabilities, pushing fixes at scale so they’re adopted fast.

Moderne DevCenter dashboard showing organizational ownership and change campaigns tracking each repository's progress toward Spring Boot 4.0, Java 25 and JUnit 6
Change campaigns in DevCenter. Each campaign tracks every repository’s progress toward the target version.

Large-scale change becomes routine when the process supports it.

Lou’s commits were sound. What alarmed the VP of Engineering was that nobody saw them coming. Tested recipes, scheduled remediation, and campaigns every team can see turn large-scale change into something the organization plans for, across every repository at once.

Written by Patricia Johnson

Originally published