The situation
The Firm runs its field operations through a ColdFusion dashboard that has been in continuous use for years. It works. It encodes a great deal of how the business actually operates, much of which exists nowhere else in writing.
It also looked its age, and the pool of developers who want to work in CFML gets smaller every year — which is a business risk long before it is a technical one.
The problem
This is the position a lot of companies with a legacy application find themselves in, and both of the obvious options are bad.
Leave it alone, and the hiring problem compounds while the interface falls further behind what staff expect from software. Rewrite it, and you take on the single most reliable way to damage a working business: a multi-year big-bang replacement that has to reach feature parity with a system whose full behaviour nobody has completely documented, during which nothing improves and everything is frozen.
The Firm did not want to gamble the operation on a rewrite, and they were right not to.
What we did
We treated the ColdFusion application as an API rather than as something to be replaced. The CFML backend stayed in place and kept serving the business logic it had always served. A new Next.js frontend was built in front of it, in TypeScript, and moved across one route at a time.
Because the cutover happened per route, the old and new interfaces ran side by side throughout. There was no date on which everything changed, and therefore no date on which everything could break.
- The legacy CFML API was preserved and continued to serve the business rules, untouched by the frontend work
- A Next.js App Router frontend was built in full TypeScript, giving the interface a type contract the original never had
- Supabase was introduced as the data layer for genuinely new functionality, rather than migrating the existing data wholesale on day one
- Migration ran route by route with no downtime, so the operation never paused for the rebuild
Why this approach is worth the extra care
Running two systems side by side is more work than running one. You maintain a boundary between them, you are disciplined about which side owns what, and for a period you are genuinely supporting both.
The trade is worth it because it removes the failure mode that actually kills these projects. In an incremental migration, the worst outcome is that a single route has to be rolled back. In a big-bang rewrite, the worst outcome is that the business cannot operate — and you typically find out late, because a rewrite is at its most fragile exactly when it goes live.
It also means the value arrives continuously rather than at the end. The Firm got a modern interface for the parts that had been migrated while the rest was still being worked on.
Where it landed
The Firm has a modern, typed frontend without having gambled the business on a rewrite, and without having thrown away years of encoded operational knowledge that was working perfectly well.
The hiring position improved too, which was a large part of the original motivation: recruiting engineers for a TypeScript and Next.js codebase is a substantially easier proposition than recruiting for CFML, even though CFML is still there underneath doing what it does well.
Client identity withheld by agreement. This account describes our own engineering work and deliberately omits any detail that could identify the client, including their name, brands, location and commercial figures.