emergesource

You inherited a codebase

There are a few ways to end up here. You acquired a company and the software came with it. The founder who wrote it left. An agency built it, the contract ended, and the handover was a zip file. Or it has simply been running so long that everyone who understood it has moved on.

However you got here, the position is the same: you own something that works, you cannot safely change it, and every estimate you get for touching it comes back either suspiciously cheap or unbelievably expensive.

Ugly is not the same as broken

The first thing worth knowing is that most inherited software is in better shape than it looks, and most first opinions about it are wrong in a predictable direction.

A developer seeing unfamiliar code for the first time will nearly always recommend replacing it. This is not dishonesty. It is that reading someone else’s code is genuinely harder than writing your own, so the rewrite feels cheaper from the inside. It is very rarely cheaper from the outside.

Software that has been in production for years, serving real customers and taking real money, has thousands of small corrections baked into it. The weird conditional nobody likes is often a customer complaint from 2019. The rewrite does not inherit any of that. It inherits the bugs instead, one at a time, in front of your customers, and it ships nothing new for six months while it does.

The question worth asking is not “is this good code.” It is: can we change it safely, and what does it cost us that we cannot?

What a real assessment looks at

I do this in about a week for a typical small system, and the output is a document you can make a budget decision from.

Can a new person run it? This is the single most diagnostic question. If someone competent can clone the repository, get it running locally, and deploy a one-line change to production without waking anyone up, most of your risk is already gone. If they cannot, nothing else matters yet.

Where is the data and is it really backed up? Not “is a backup configured.” Has a backup been restored, by someone, recently, into a working system. Untested backups fail at roughly the rate you would expect from things nobody has ever checked.

What is holding it up? The runtime, the framework, the database, the hosting. How far behind is each, is there a supported upgrade path, and is anything on a version that no longer receives security fixes. This is where genuine forced work lives.

What is undefended? Which parts of the system have no tests, no monitoring, and no alarm — and of those, which ones touch money or customer data. The overlap between “nobody is watching” and “this handles payments” is the actual risk register.

What have the logs been saying? Error monitoring in an inherited system is usually either absent or full of thousands of ignored alerts. Both are informative. The ignored ones frequently contain the bug you have been describing to me as a mystery.

What does it cost to run? Inherited infrastructure is routinely two to five times more expensive than it needs to be, because it was sized for a launch that happened years ago and nobody has looked since. This one occasionally pays for the whole engagement.

The order the work goes in

Stabilise first, understand second, improve third, and only then consider replacing anything. In practice:

  1. Backups and access. Provable restore, and accounts your business owns.
  2. Deployability. One command, repeatable, reversible.
  3. Observability. Errors and uptime visible somewhere a human will see them.
  4. Documentation. A short runbook, written while learning the system, because that is the only moment anyone can see what is non-obvious.
  5. The thing that is actually hurting you. Now it is safe to touch.
  6. Dependency and platform currency. Boring, forced, schedulable.
  7. Replacement, if it is still justified. By now you will know, and usually the answer has changed.

Steps one through four are cheap and change your position enormously. Most people expect the project to start at step five and are surprised how much better things feel before it does.

What I do

I become the technical owner. Not a report, not a recommendation deck — I do the stabilising work, I run it afterwards, and I am still there in month nine when something breaks at an inconvenient time.

That usually starts as a fixed-price assessment and stabilisation project, then rolls into a monthly retainer if you want someone to keep owning it. Plenty of people stop after the project, with a system they can hand to anyone. That is a fine outcome and I will not pretend otherwise.

What it costs

The engineering assessment is fixed-price and takes two to three weeks. Stabilisation work after it is fixed-price once scoped, and ongoing ownership is month to month.

Compare against the two alternatives honestly. A senior hire is $150k plus benefits, recruiting, and the three months before they are useful. A rewrite is usually six figures and a year during which your product does not move.

Common questions

How do you assess a codebase you have never seen?

By running it, not by reading it. The first question is whether a new person can get it working locally and deploy a trivial change safely — that single exercise surfaces more real risk than a week of reading source code. After that: where the data lives and whether it is backed up, what the dependencies are and how far behind they are, what has no tests around it, and what the error logs have been quietly screaming about. A useful assessment takes about a week for a small system.

Should we rewrite it or fix it?

Fix it, almost always. A rewrite means paying again for every decision the original developers made, including the ones nobody remembers making, while shipping nothing new for months. Rewrites are justified when the platform itself is genuinely dead — an unsupported runtime with security holes and no upgrade path — or when the software is small enough that the rewrite is measured in weeks. Ugly is not the same as unmaintainable.

We acquired a company and got their software. Where do we start?

Start with what would hurt most if it stopped. Not the tidiest starting point, the riskiest one: where the customer data is, whether it is backed up, who can access production, and what happens if the one remaining person who knows the system leaves. Technical debt is a budget question and can wait. Single points of failure cannot.

Is bad code actually a business risk or just an engineering complaint?

It becomes a business risk at the point where it changes what you are able to decide. If you cannot launch a pricing change because nobody is confident touching the billing code, the code is now setting your strategy. Until it does that, it is a preference. That distinction is worth holding onto, because a lot of rewrite proposals are really taste arguments wearing a risk costume.

Start with a call

Thirty minutes. Tell me how you ended up with it and what you are afraid to touch, and I will tell you roughly what you are looking at.

→ Book a 30-minute call

Also worth reading