
Building with Legacy Software: Lessons from 15 Years of Evolution and Optimization
We would like to share some of the experiences we’ve had over the past 15 years working on critical software with a complex legacy component. It dates back to the 1980s and has evolved into a powerful system packed with domain knowledge and smart algorithms. Its “killer feature” is its ability to handle complex geometries. Over the years, the program has more than proven its value.Â
However, systems with such a long history are rarely simple. The software initially consisted almost entirely of production code, with no test suite. As a result, no one dared to modify the code. To break this cycle, we didn’t opt for a radical restart, but chose a step-by-step approach.Â
Be HumbleÂ
When we started, the code had a reputation for being inaccessible to new team members, largely written in old Fortran dialects with some C. It was complex and clearly rooted in 1980s paradigms. Yet we quickly learned that first impressions can be misleading. What seems outdated is often well thought out—if you take the time to understand it.Â
Respecting the work of our predecessors was crucial. Only by genuinely trying to understand their choices could we see the value and potential of the system. That sometimes also meant acknowledging that later additions had made the original design less clear.Â
Changing Norms, Enduring ValueÂ
The tools and methods we use to develop software are constantly evolving. This code maintained an extensive administration for its own memory manager—something modern compilers now handle automatically. We replaced this component step-by-step with a more standard approach. We did this systematically, in such a way that each change could be made incrementally while everything continued to work.Â
We also modernized the system in other ways, switching to Fortran-90 modules and introducing more compiler checks. Entire sections of code could be replaced with standard functions. This also helped when onboarding new developers, who were more willing to stay involved with the project.Â
We learned that modern standards don’t automatically mean you have to rewrite everything. Often, it’s better to gradually integrate them into what already exists. This allowed us to bridge the gap between old and new without losing the trust of users or developers.Â

A New LifeÂ
Code often lasts much longer than expected. And that meant making choices that promoted sustainability. Alongside maintenance, we always focused on delivering new value to users. Even when rewriting became necessary, we ensured that at least half our time was spent on new features. This kept us relevant and helped maintain our client’s trust.Â
When the program was eventually mostly phased out, a crucial part—the computational core—remained intact. We repackaged it as a standalone library that is still in use today. A quiet reward for the effort to not just keep the system running, but also make it transferable and future-proof.Â
Creative Process or Standard Playbook?Â
Is there a standard recipe for dealing with legacy software? No—every situation requires a tailored approach. With legacy code, ideal standard solutions are often not feasible. Creativity is needed to see what is possible and how to work toward it while everything keeps running. Sometimes that means using “messy” interim solutions or temporary hacks you later clean up. What matters is the end goal: a robust system that is alive, evolving, and has a future.Â
Rather than aiming to do everything perfectly at once, we work in pragmatic, systematic steps. Because in legacy development, the ideal plan is rarely achievable—but with a “good enough” plan, executed with care and attention, you can often move forward for decades.Â
More information
If you want to know more about working with legacy software, check out our whitepaper or contact us.