The strangler fig grows around a host tree, puts down its own roots, and eventually stands on its own while the host is gone. Martin Fowler borrowed the image for a way of replacing a large system: build the new one around the edges of the old, route traffic to the new pieces as they are ready, and let the old system shrink until it can be switched off.
For a large existing Java or .NET monolith, this is still the only approach that does not require a feature freeze or a leap of faith. What has changed is who does the building. AI coding tools such as Kiro, Claude Code, AWS Transform, and others can now write the extracted services. The pattern is how you keep them pointed at the right thing.
Why not a rewrite
A big-bang rewrite needs the old system to stand still while the new one catches up, and large systems do not stand still. It also needs someone to know every business rule the old system enforces, and in a system that has been changed by hundreds of people over a decade, those rules live in the code and nowhere else.
The strangler pattern avoids both problems. Each extracted domain delivers value on its own. Each failure is small and reversible: a routing rule points back at the monolith and the day continues. Your team controls the pace. There is never a second codebase to maintain in parallel, because the monolith is the fallback until the moment it is not needed.
The six steps
1. Find the real domain boundaries. Not the ones on the architecture diagram; the ones in the running application. Observe which classes, resources, and database tables are used together in production and which are used exclusively by one part of the system. Exclusivity is the measure that matters: a candidate domain whose classes and data belong only to it can be extracted cleanly; one that shares most of its classes with the rest of the monolith cannot, yet.
2. Choose the first domain. Start with functionality that is already relatively decoupled, or that changes most often (so the payoff is immediate), or that blocks the business goal most directly. Avoid starting with the database layer or the user interface; business logic comes first, data second, UI last. Decouple vertically when you can: the logic, its data, and its interface together.
3. Extract it, and only it. Define what the new service does in a specification derived from the monolith’s actual behavior (choosing refactor, rearchitect, or rewrite for the domain is its own decision). Build it as a service with its own deployable unit. New functionality from this point goes in the new service, never back into the monolith.
4. Prove it behaves like the old code. Run the new service alongside the monolith and compare responses. Integration tests generated from how the monolith actually runs in production are the guardrail here: they encode the behavior the business depends on, including the rules nobody wrote down.
5. Route traffic through a façade. A routing layer sends each request to the monolith or the new service. It needs to survive batch surges, enforce authentication between services, and roll back to the last known good route automatically when a new service misbehaves. Retries and circuit breakers keep one failing service from cascading.
6. Repeat until the monolith is gone, or small enough to keep. Not everything needs to be extracted. Pick the ending point deliberately: some functionality has too little exclusivity or too little complexity to justify being a separate service, and it can stay in a smaller, healthier core.
Judgment calls the pattern does not make for you
The steps are mechanical; the decisions inside them are not.
Consolidate before you extract. Two candidate domains that overlap heavily are one domain. Merging them first avoids extracting the same logic twice.
Name services for what they do. A service named after the team that built it, or after the monolith’s package structure, carries the old architecture into the new one.
Decide what stays. A shared utility used by every domain is not a microservice; it is a library. A small, stable piece of logic with no independent scaling need is not worth the operational cost of a separate deployment.
Kill the dead code. Every large monolith carries code that no production flow reaches. Extracting it wastes effort and preserves debt. The runtime data that shows you domain boundaries also shows you what is never called.
What the pattern needs from AI coding tools, and what they need from you
The strangler pattern was always limited by the labor in steps 1, 3, and 4: understanding the boundaries, writing the extracted service, and proving it correct. AI coding tools have removed the constraint on step 3. A tool given a bounded, well-specified domain writes the service well.
What the tools cannot do on their own is steps 1 and 4 on a large existing application. Past roughly 500,000 lines of code or 1,000 classes, the system does not fit in a context window, and static analysis shows every dependency with no signal about which ones matter in production. A tool working from the code alone will guess at boundaries, and its guesses are what create the distributed monolith that gives microservices a bad name.
So the pattern in 2026 looks like this: runtime analysis establishes the boundaries and the exclusivity data, your architects set the target architecture, a specification and integration tests are produced for each domain, and the AI coding tools do the extraction one domain at a time with your team reviewing each change.
Where vFunction fits
vFunction is a modernization platform for large existing Java and .NET applications. Using runtime analysis and proprietary data science, it captures how the monolith actually runs in production, measures exclusivity, surfaces dead code and shared classes, and helps your architects define the target architecture before the first extraction. It generates a specification for each domain from the observed runtime flows and integration tests from the same data. Kiro, Claude Code, and other AI coding tools receive them through vFunction’s MCP server and downloadable skills and extract or rewrite the domain under your team’s review; AWS Transform is used within the same workflow for .NET and Java upgrades. vFunction’s engineers run the process with your team until your team can run it alone.
Keep learning: Monolith to microservices: all you need to know · Modernize Large VM Apps to Containers