---
name: app-modernization
description: Modernizes legacy applications incrementally — strangler-fig slices, expand-contract data migrations, parity-verified cutovers, and clean decommissioning. Use when migrating a monolith or legacy stack, upgrading frameworks in place, extracting services, replatforming, or when the user mentions modernization, migration, or a legacy rewrite.
category: architecture
keywords: legacy, strangler-fig, migration, replatform, cutover, parity, expand-contract, decommission, monolith, modernization
---

# App Modernization

Modernization is incremental replacement behind a stable facade, not a rewrite. The legacy system encodes years of fixed bugs and business rules nobody documented; the goal is to move off it without losing either. Every slice ends in production — a modernization that lives on a branch is a science project.

## When to apply

Use when migrating a legacy or monolithic application to a modern stack, upgrading a framework in place, extracting services from a monolith, replatforming (cloud, runtime, database), or whenever someone proposes "just rewrite it".

## Workflow

1. **Assess** — inventory modules, dependencies, data stores, and integration points. Score each on business value × change risk. Output: a ranked list of migration slices. Modernization is a portfolio decision before it is a code exercise.
2. **Pick the seams** — find (or carve) module boundaries where old and new can coexist behind a facade, interface, or route table. No seam, no slice — do the modularization work first.
3. **Slice** — order slices by value ÷ risk. The first slice is a tracer bullet: small, high-visibility, low blast radius. Each slice ships to production before the next starts.
4. **Choose the per-slice pattern** — from the pattern table below; one pattern per slice, written down before code.
5. **Verify parity** — the new path proves it behaves like the old one on real cases (fixture-driven round trips, golden-master diffs) *including the weird legacy edge cases*, before any traffic moves. Document deliberate deltas; don't silently "fix" behavior.
6. **Cutover** — route a fraction of traffic (or one tenant/flow) to the new path, watch the signals, widen, flip. Every cutover has a rehearsed rollback — if you can't roll back, you're not cutting over, you're betting.
7. **Decommission** — delete the old code path, its tables, its feature flags, its deploy config, its runbook. Done means the old thing is gone, not that the new thing works.

## Migration patterns

- **Strangler fig** — grow the new system around the old; route at a facade; delete old code per slice. The default choice.
- **Branch by abstraction** — for in-place framework upgrades: old and new implementations behind one interface, flip callers one at a time.
- **Parallel run (shadow)** — run new alongside old on live traffic and diff outputs. The cure for "we don't actually know what this code does".
- **Expand–contract** — for schema and API changes: add the new shape, migrate writers/readers, contract (remove) the old. Never a breaking in-place change.
- **Dual-write → backfill → verify → read-switch** — for data: write both stores, backfill history, verify counts and checksums, switch reads, stop writing old.

## Rules

- No big-bang rewrites — a rewrite re-learns every bug the legacy code already fixed and freezes feature delivery for its duration.
- Behavior first, structure second — changing what the system does and how it's built at the same time makes every regression ambiguous. Sequence them.
- Every cutover has a tested rollback — rehearsed, not theoretical.
- Decommissioning is part of done — a leftover half-old system rots, confuses on-call, and doubles the maintenance bill.
- Parity over perfection — match current behavior before improving it; improvements get their own slices.

## Related skills

- [round-trip-testing](/skills/round-trip-testing) — proving old/new parity with fixture-driven round trips.
- [domain-modularization](/skills/domain-modularization) — carving the seams before you slice.
- [lean-implementation](/skills/lean-implementation) — keeping each slice minimal and shippable.
- [minimal-fix](/skills/minimal-fix) — the shape of individual fixes made during migration.
