Over the past few weeks, I’ve been talking to engineering leaders who’ve gone through M&A. Not the announcement. Not the strategy deck.
The part where you actually have to make two or three different stacks behave like one system. One conversation stuck with me. An engineering leader at a publicly traded company running a real-time logistics system put it pretty bluntly:
Coding’s not really the bottleneck anymore. It’s the decision making. Getting everyone aligned is the hard part.
That gap is where these efforts slow down. This looks like a code migration problem. It isn’t. It’s a product decision problem that shows up in code.
At the beginning, it feels straightforward.
Multiple systems. Some duplication. A clear need to standardize.
Then you get into the details.
Two systems both have a “checkout flow.” Except they’re not actually the same.
One supports a dozen countries, with tax and compliance logic scattered across multiple services. The other only handles the US, but has better fraud detection and a simpler UX.
Now you’re not migrating code.
You’re deciding which version of reality survives.
Do you merge them? Rewrite them? Kill one?
None of those are safe choices. And everyone involved knows it.
That’s when things slow down.
Every team hits this.
In theory, you build one system.
In practice, every market has exceptions. Regulations, taxes, weird edge cases that only exist in one place.
You can try to support everything, and your clean system turns messy again.
Or you standardize aggressively, and now local teams are telling you you’ve broken critical flows.
There isn’t a clever solution here.
Just tradeoffs you have to own.
You’d expect strong teams to converge quickly on the “right” architecture.
They don’t.
Everyone has context. Nobody has the full picture.
So you get long debates where every option sounds reasonable and none feel obviously correct.
Without clear ownership, these drag on. Work pauses. Then the same conversation comes back a few weeks later.
From the outside, it looks like slow execution.
From the inside, it’s risk avoidance.
The clean parts of the system usually have owners.
The messy parts don’t.
And that’s exactly where migrations get stuck. Edge cases, legacy behavior, features that don’t map cleanly to the new system.
Teams will migrate what they own.
The ambiguous pieces sit there until they become everyone’s problem.
This is the part most teams miss.
Refactors are faster now. Boilerplate is faster. Even large-scale changes are easier than they used to be.
But overall progress hasn’t improved.
Because the constraint moved.
Now you can try more approaches, which creates more debates. And because the system is bigger, the cost of being wrong is higher.
So everything funnels into one place:
Decisions.
Most teams still operate like code is the scarce resource.
It isn’t.
These efforts don’t fail because one team can’t do the work.
They fail because twenty teams don’t move together.
The same patterns show up:
- Teams slow down when they don’t see progress elsewhere
- Dependencies pile up faster than expected
- There are more meetings, but not more decisions
At that point, progress depends less on engineering and more on coordination.
And most teams underestimate how hard that is.
Codemod doesn’t solve your architecture debates.
It doesn’t tell you which product direction to pick.
What it does is remove a lot of the friction that surrounds those decisions.
In most migrations, a large portion of the work is mechanical:
- API changes
- Renames
- Config updates
- Repetitive refactors across many repos
That’s the obvious part Codemod handles.
The less obvious part is what it does for visibility and coordination.
With Codemod Campaigns, you can see what’s actually happening across your codebases in real time:
- Which repos are done
- Which ones are partially migrated
- Where things are breaking
- How much work is left
This changes how leaders manage these efforts.
Instead of chasing updates across teams or relying on status meetings, you can answer basic questions directly:
- Are we actually making progress?
- Where are we stuck?
- Is this initiative worth continuing?
It also changes how migrations roll out.
Instead of coordinating a massive effort upfront, teams can start small:
- Run a campaign on a subset of repos
- Validate the approach
- Fix edge cases early
- Build trust with real results
- Then scale
That reduces coordination overhead significantly.
You don’t need layers of TPMs trying to reconstruct status from scattered updates.
You don’t need to guess whether things are on track.
And in practice, that leads to outcomes like:
- Migrations finishing ~2x faster
- Engineering cost dropping significantly (often close to 1/5 of what similar efforts used to take)
- Fewer coordination bottlenecks
Not because the hard decisions disappeared.
But because everything around those decisions became easier to manage.
A good example of this in practice comes from Netlify.
They needed to roll out large-scale changes across many codebases without slowing teams down or introducing risk.
Instead of trying to coordinate everything manually, they used Codemod to:
- Automate repetitive changes across repos
- Track progress centrally
- Roll out changes incrementally instead of all at once
That let them move faster without losing control of the process.
If you want the full breakdown, it’s worth reading the case study here:
https://codemod.com/blog/netlify-case-study
This is where I’d expect most teams to underestimate the impact.
Before:
- Progress tracked in spreadsheets or status meetings
- Hard to tell what’s actually done
- Surprises show up late
After:
- Real-time view across all repos
- Clear understanding of progress and blockers
- Fewer surprises, faster decisions
None of this removes the hard parts.
Every team still has to make uncomfortable decisions.
Drop features. Pick one system over another. Simplify things that used to be flexible.
If you try to avoid that, you end up in a worse place.
A “unified” system that still behaves like multiple systems glued together.
The teams that make real progress have one thing in common:
This isn’t treated like a side project.
It has executive backing. Clear priority. Real accountability.
Anything less, and it drags.
If you’re heading into one of these, be honest about what you’re doing.
You’re not just migrating code.
You’re forcing a set of decisions that used to live in isolation into one shared system.
That’s where the risk is.
That’s where things slow down.
And that’s the part you actually need to manage.
If your migration is stuck, stop asking how to rewrite the code.
Start asking who’s allowed to decide what the system should be.