Modernize a legacy system when it costs more to keep than to change: changes that should take days take weeks, the platform no longer gets security patches, or only one person dares to touch it. For most companies the safest route is step by step, replacing or refactoring one part at a time while the old system keeps running. This guide is for CTOs, IT managers and owners of business-critical systems, and it describes how we run our software modernization work, which starts with a code audit from €1,900.
By legacy software we mean any system the business still depends on but that has become hard and risky to change. Age isn’t the test. A 15-year-old system with tests and current dependencies can be in better shape than a three-year-old one nobody understands.
What are the signs it’s time to modernize?
One of these signs is a reason to plan. Two or more usually mean the system already costs you more than it saves.
| Sign | What you notice | What it usually means |
|---|---|---|
| Changes take weeks, not days | Small requests queue up and estimates keep growing | Tangled code with no tests, so every change needs manual checking |
| No more security patches | Your dependency scan flags issues nobody can fix without a major upgrade | The runtime or framework has reached end of life |
| Integrations need workarounds | Connecting Fortnox, Visma, a payment provider or an AI API takes weeks of glue code | No clean API layer; data locked in the old structure |
| Incidents are up | More outages, and each one takes longer to diagnose | Missing monitoring and accumulated complexity |
| One person understands it | Holidays and sick leave become a business risk | Knowledge lives in someone’s head, not in documentation and tests |
| Hiring is hard | Candidates and consultants decline once they see the stack | Few engineers want to, or can, work in it |
| Scaling means more hardware | Every performance problem is solved with a bigger server | Limits in the architecture, not in capacity |
The second row is the one with a deadline. Frameworks and runtimes stop receiving security fixes on a published date: PHP 7.4 reached end of life in November 2022, AngularJS at the end of 2021 and Python 2 in January 2020. If your system runs on something like that, every new vulnerability stays open. With NIS2 and customers’ security questionnaires asking how you patch, that is a business problem as much as a technical one.
When is modernizing not worth it?
Leave a system alone if it is stable, still patched, rarely needs to change and nobody is waiting for new features from it. Modernization pays off through faster change and lower risk, and a system that doesn’t need to change gets little of either. Keep it patched and monitored, document it so it isn’t a one-person system, and spend the budget where it moves the business.
Which modernization approach fits your system?
There are five realistic options. They aren’t exclusive: many projects combine two, for example re-platforming first and then replacing the worst modules one by one.
| Option | What changes | Choose it when | Main risk |
|---|---|---|---|
| Refactor | The code’s structure, not its behavior | The platform is still supported and the business logic is sound, but the code is hard to work in | Endless clean-up with no visible result unless it is tied to features |
| Re-platform | Hosting, runtime or framework version, with minimal code changes | The code is acceptable but runs on end-of-life software or fragile, expensive servers | Hidden dependencies on the old environment |
| Strangler-fig rewrite | Modules are rebuilt one at a time behind a routing layer | The system is large and business-critical, and parts of it need to work differently | Two systems run in parallel for a while; it takes discipline to finish |
| Replace with off-the-shelf | The system is retired in favor of a SaaS or standard product | What it does is no longer unique to your business, such as invoicing, HR or a standard CRM | Process changes, data migration and limits on customization |
| Big-bang rewrite | Everything at once, cut over on one date | Rarely: a small system with little reusable logic | Value arrives only at the end, and edge cases the old system handled get lost |
The strangler fig pattern gets its name from a fig that grows around its host tree until the tree is gone (Martin Fowler’s original description). You put a routing layer in front of the old system, build a new module behind it, move traffic for that function to the new module and switch the old code off. Then you repeat until nothing of the old system is left.
Replacing with an off-the-shelf product is underrated. If your custom system now does what Fortnox, Visma, HubSpot or a standard e-commerce platform does well, the cheapest modernization may be to retire it and keep a small integration for the part that is genuinely yours. We compare the two in custom software vs off-the-shelf.
How do you modernize without a big-bang rewrite?
This is the sequence we follow. The order matters more than the tools.
- Audit and map the system. Read the code, list dependencies and their support status, map integrations and data flows, and find out who uses what. The output is a written report with prioritized risks and a phased roadmap.
- Put a safety net in place. Set up CI, monitoring, tested backups and characterization tests, which record what the system does today so you notice when a change alters it. Without this, every later step is a gamble.
- Fix urgent security issues first. Unpatched dependencies, secrets in the code and shared admin accounts can’t wait for the roadmap.
- Pick the first slice. Choose a module that changes often, has clear boundaries and hurts the business today, such as invoicing, a customer portal or a reporting export. Don’t start with the core that everything else depends on.
- Route, build, compare, switch. Add the routing layer, build the new module, run it in parallel and compare its results with the old one, migrate its data, then move traffic over, in stages if you can.
- Switch off the old code. Delete what the new module replaced. A strangler-fig project that never removes anything has only made your system bigger.
- Keep shipping features. Don’t freeze the roadmap for months. Build new features in the new parts of the system, which is also how you show the rest of the business what the work is for.
A worked example: replacing an order system piece by piece
This is a composite example, not a specific client. A company runs a 12-year-old PHP order-management system used by sales, the warehouse and finance. It runs on an end-of-life PHP version, sends a nightly CSV file to the accounting system, and only one developer knows how the pricing rules work.
- Weeks 1–2: audit and roadmap. The biggest risks turn out to be the PHP version and the nightly export, which sometimes fails without anyone noticing.
- First phase: upgrade to a supported PHP version, add characterization tests around pricing and order creation, move secrets out of the code and set up monitoring. Users see no difference, but the system is patched and its riskiest logic is under test.
- Second phase: a new invoicing module behind a routing layer, talking to the accounting system through its API instead of a CSV file. Old and new invoicing run in parallel until the numbers match, then the old path is switched off.
- Third phase: a customer portal that reads order status through a new API, so customers stop emailing to ask.
- Later phases: the internal admin screens, module by module, until the old application can be retired.
Every phase ends in production. If the budget is cut after the second phase, the company still has a patched system and a working accounting integration, not half a rewrite.
How much does modernization cost, and how long does it take?
Cost depends less on lines of code than on how much undocumented business logic they hold, how many integrations there are, how messy the data is and how much is already covered by tests. These are our published prices, excluding VAT:
| Step | Price | Typical duration |
|---|---|---|
| Code audit with a written, phased roadmap | From €1,900, fixed price | 1–2 weeks |
| Modernization project, fixed price per phase | Typically within our €30,000–150,000 project range | 3–6 months |
| Keep the old system patched while you modernize (Care Lite) | €4,200/month | Month to month |
| Ongoing modernization alongside new features (Start or Scale Pod) | €8,200 or €14,000/month | Month to month after the first month |
A Delivery Pod is a fixed-price monthly team led by a senior engineer. Care Lite covers maintenance, security updates, monitoring and small fixes, but no new features, which makes it a good fit for the old system while the new parts are built.
The engineering is done by our team in Ukraine, with a senior engineer responsible for architecture and code quality and a founder accountable for the project. You sign with Smoother Development AB under Swedish law. Most audits only need read access to the code; if the work requires access to personal data, we sign a data processing agreement with the EU Standard Contractual Clauses first. For how project pricing works more generally, see how much custom software development costs.
How do you get the business to agree?
The hardest part is often not technical. The system works, more or less, and the cost of keeping it is spread across many small delays. Make that cost visible before you ask for a budget:
- Track for a month how engineering hours split between maintenance and new work.
- List last year’s incidents and what each one cost in staff time or lost orders.
- List initiatives that were postponed or dropped because the system couldn’t support them.
- Write down what happens if the one person who knows the system leaves.
Then compare two plans over two to three years: keeping the system as it is, and a phased modernization where each phase ships something. The phased plan is also easier to approve, because the business can stop after any phase and still keep what it paid for.
What if the legacy system is a new app built with AI tools?
Not every system that’s hard to change is old. Apps built quickly with Lovable, Bolt, Replit, v0 or Cursor often hit the same walls within months: no tests, open database rules, fragile login and every change breaking something else. That is usually a stabilization job rather than a modernization project. Our Vibe-Code Rescue starts with a code and security audit from €1,900 (3–5 business days for a typical app), followed by a fixed-price stabilization from €6,000, typically 2–4 weeks.
What to do next
If two or more of the signs above sound familiar, start with the code audit. Within 1–2 weeks you get a written picture of the risks, the options that fit your system and a phased plan with a fixed price for the first phase, and you decide from there. You can book it through our software modernization page.