How to transform legacy software into a modern product

Nobody chooses legacy software. It builds up until every feature takes longer, every deploy feels risky and hiring developers gets harder. The good news: you don’t need a full rewrite.

Marco MendãoCo-Founder & CTO · 11 min

When software and infrastructure are both behind

Legacy is not just old code. It is the whole stack:

  • Application: monoliths, outdated dependencies, no tests, tightly coupled features.
  • Data: old schemas, missing indexes, business logic buried in stored procedures.
  • Infrastructure: bare metal or early cloud, manual deploys, no staging that mirrors production.
  • Operations: teams firefighting and quarterly releases because each one is feared.

Breaking the monolith into manageable parts

The monolith is not bad in itself. The problem is shared tables and implicit dependencies that make any change risky. The goal is not microservices for their own sake. It is finding bounded contexts: billing, user management, reporting or the workflow customers use every day.

  1. Map the system: what exists, who uses it and where it hurts most.
  2. Find the natural seams: modules with few dependencies.
  3. Extract one slice at a time, starting with something valuable but isolated.
  4. Define clear interfaces: APIs, events or shared contracts.
  5. Keep the monolith running while new services take on responsibilities.

Rebuilding features is a product decision

Rebuilding a feature is not translating code. It is the chance to question every screen, field and step. Talk to users and support before coding, simplify workflows that piled up "just one more field", write tests for the new version and run both systems in parallel until you trust parity.

Example: Evolve RHEvolve RH’s software already existed, but the process for managing payslip sending had gaps. We found a clear module in the old software, isolated it and rewrote it: that solved the problem and added new capabilities to the feature.

Choose technology the team can run in production, not the newest: a PWA instead of a desktop-only client, managed databases instead of servers nobody maintains, automated deploys instead of FTP uploads.

Infrastructure as the bridge

Both systems will live side by side for months. Infrastructure makes that invisible to users:

  • Reverse proxies (nginx, Traefik, Cloudflare) route traffic to old or new by URL, feature flag or segment.
  • Load balancers allow zero-downtime deploys and instant rollback.
  • API gateways centralise authentication, rate limiting and routing.
  • Message queues let both systems talk without tight coupling.
  • Feature flags release to a share of users before full cutover.
This is the strangler fig pattern: the new system gradually wraps and replaces the old one, branch by branch, without users changing URL.

Divide and conquer, but stay lean

  1. Pick the highest-impact, lowest-risk slice.
  2. Set a hard deadline: 4 to 8 weeks until the first slice is live.
  3. Keep a small, dedicated squad.
  4. Measure outcomes: deploy frequency, incidents, satisfaction and time to the next feature.
  5. Celebrate each cutover as real progress.

Where to start

Start with an honest audit and find the biggest cost: slow releases, developer turnover, customer complaints or infrastructure bills. Then pick the pain that maps to an isolable product slice and build the bridge.

Marco Mendão
written byMarco MendãoCo-founder and CTO at Betacode. Writes about architecture, product engineering and using the right technology to ship faster.
// next step

Want to apply this to your project?

Tell us what you are building and we will talk about the best approach.

Talk to us Estimate price

Keep reading

All insights →
Engineering9 min
Building applications with JavaScript/TypeScript as the backboneRead article →
Business10 min
Why Lean Startup is Betacode’s Rosetta StoneRead article →