DEV Community

Cover image for Who Here Has Worked with Legacy? The Longer You Wait, the Worse It Gets

Who Here Has Worked with Legacy? The Longer You Wait, the Worse It Gets

Sylwia Laskowska on June 18, 2026

I promised myself that starting this week I'd switch to lighter topics. But on Monday, my JSNation adventure officially came to an end, and I reali...
Collapse
 
gramli profile image
Daniel Balcarek

Excellent article! This reminded me of one of my own migrations.

My last migration was from an old PowerBuilder desktop application. In our case, migration was no longer optional: the only developer who truly understood the app had already retired, there was almost no documentation and the codebase was a mess. ๐Ÿ˜„

We tried to follow the Strangler Fig pattern, but the business logic was so tightly coupled that we had to take a more waterfall-like approach and migrate large features end to end. It was not necessarily the safer approach, but without it, we would have ended up with hundreds of feature flags and an even harder system to manage.

That made the risk very real and it showed exactly why waiting only makes legacy systems harder and, in some cases, ultimately much more expensive to replace.

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

That's so true. We all love talking about patterns and best practices, and then reality shows up. ๐Ÿ˜„

Sometimes the textbook solution simply doesn't fit the constraints of the project, and you have to adapt. In the end, getting the migration done is more important than following a pattern perfectly.

And honestly, your story reinforces what might be the main message of the article: don't postpone migrations. The longer you wait, the fewer options you have, and the more expensive and risky everything becomes.

Collapse
 
gramli profile image
Daniel Balcarek

Exactly. As always in software development, it is all about trade-offs.

I agree, but at the same time, I understand why migrations get postponed, a running product still needs to generate revenue and migrating a legacy system can require a significant investment.

Maybe the better approach is to continuously maintain and modernize the product before a full migration becomes unavoidable. That also requires budget, but in the long run, it can be much cheaper and less risky than being forced into a large migration later.

Thread Thread
 
sylwia-lask profile image
Sylwia Laskowska

Exactly! These things are never easy.ย 

But I've seen migrations postponed even during relatively quiet periods because they were considered annoying and disruptive. Product owners would complain that they were a burden for developers, testers, and everyone involved. That's when my favorite argument came into play: security. ๐Ÿ˜‚

I'd scare them a little, and later they'd thank me when customers started running security audits. What a surprise. ๐Ÿ˜„

And yes, continuous maintenance is definitely the best approach. A migration from Angular 7 to 21 is a nightmare, but going from 21 to 22 is almost trivial. That's the beauty of keeping things up to date: future migrations become boring, which is exactly what you want.

Collapse
 
xulingfeng profile image
xulingfeng

That "temporary" adapter joke hurt ๐Ÿ˜‚ We had one of those bridge solutions hanging around for three years before someone finally killed it. Nobody even remembered what it was for anymore. Thanks for writing this.

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

Hahaha, exactly! ๐Ÿ˜„ That's how those "temporary" adapters usually end up.

And honestly, the only thing worse than finding one after three years is realizing that it's still needed after three years. ๐Ÿ˜‚

Collapse
 
xulingfeng profile image
xulingfeng

And nobody dares to touch it because 'it still works' ๐Ÿ˜‚ until it doesn't.

Thread Thread
 
sylwia-lask profile image
Sylwia Laskowska

Hahaha, exactly! ๐Ÿ˜„ Or some nasty security vulnerability shows up and suddenly everyone is shocked. ๐Ÿ˜‚

Collapse
 
buildbasekit profile image
buildbasekit

Every legacy system has that one file named utils.js, helpers.java, or final_final_v2.cs.

Nobody knows who wrote it.

Nobody knows what it does.

But everyone agrees touching it requires a change request, a rollback plan, and a prayer. ๐Ÿ˜…

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

Hahaha, exactly! ๐Ÿ˜‚ Every legacy system has one of those files. Even the coding agent takes one look at it and submits its resignation. ๐Ÿ˜„

Collapse
 
buildbasekit profile image
buildbasekit • Edited

๐Ÿ˜‚ Somewhere inside that file is a comment from 2018 that says:

// temporary fix

And everyone is too afraid to ask temporary for whom.
๐Ÿคฃ

Thread Thread
 
sylwia-lask profile image
Sylwia Laskowska

Hahaha, exactly! ๐Ÿ˜‚ Maybe they meant temporary on a cosmic scale. ๐Ÿ˜„

Like, "temporary" for the remaining lifetime of the Universe.ย ๐Ÿคฃ

Collapse
 
hemapriya_kanagala profile image
Hemapriya Kanagala

Sylwia, this brought back memories ๐Ÿ˜„

I've worked on legacy systems before, and one thing I've learned is that they usually look much simpler from the outside than they actually are. Once you start digging, you realize how many decisions, dependencies, and business rules have built up over the years.

A lot of the time, there is a reason things ended up the way they did, even if it isn't obvious at first.

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

Exactly! ๐Ÿ˜„ And until you've spent enough time in the project, you usually don't know what those reasons are.

People often assume that legacy code exists because somebody was incompetent. Then you dig into the history and discover that, six years ago, half the team left and two juniors were left on their own for six months, doing the best they could under the circumstances. ๐Ÿ˜‚

Most of the time, there is a story behind the mess. And understanding that story is often harder than understanding the code itself.

Collapse
 
newadventuresinit profile image
Dirk Mattig

First of all, it is always reassuring to learn that other developers face similar challenges in their projects and that I am not the only one who regularly ends up in impossible situations ๐Ÿ˜‚

In my experience, front-end migrations pose an additional non-technical challenge: they directly affect the user experience. The moment anything looks even slightly different than before, screenshots have to be retaken, manuals have to be updated, and users have to be retrained. It is even possible that UI changes touch on legal issues, and you need approval from a governance body first. Accessibility is another topic I will not even get into now.

Back-end migrations are easier in this respect, but on the other hand, the customer is far more afraid that you will break the business. Shortly before the advent of AI, I was asked to consult on a COBOL migration project. The last of their developers was about to retire. After a long and winding road, the project decided to post a job advert for a new programmer. You should never underestimate how many red flashing warning lights humans can ignore for how long ๐Ÿ˜†

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

Oh yes, absolutely. ๐Ÿ˜„ Frontend migrations almost always end up changing something in the UI, even if you're using a standard component library like Material. Fortunately, my experiences have generally been positive. Customers were happy because things looked cleaner and more modern. Of course, that's only true as long as the changes are relatively small. God forbid you change something significant, even for the better, because then everyone suddenly starts missing the old version. ๐Ÿ˜‚

And I love that COBOL story. What resonates with me most is the part about humans being able to ignore red flashing warning lights for years. I've seen that so many times.

To be honest, I consider myself a fairly average senior developer in terms of pure technical skill and architecture. But I do have one thing that often pushes me into tech lead roles: social skills. ๐Ÿ˜„ Sometimes I'm actually able to convince the business to listen to reason and deal with problems before they become catastrophes. Not always, of course, but often enough to make a difference. ๐Ÿ˜…

Collapse
 
marina_eremina profile image
Marina Eremina

I wonder if simply showing the article's title image would be enough to convince stakeholders to migrate to a new stack. It looks surprisingly convincing! ๐Ÿ˜„

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

Hahaha, exactly! ๐Ÿ˜„ We all prefer living in the shiny city of the future rather than in a gloomy industrial landscape that feels like Eastern Europe in the 90s. ๐Ÿ˜„

Collapse
 
kenwalger profile image
Ken W Alger

Great read! You make a lot of excellent points about the psychological and technical friction of migrations, especially on the front end, where frameworks move at lightning speed.

But your post also made me think about a completely different tier of "legacy" code, the kind that doesnโ€™t just predate modern frameworks, but actually predates the public internet entirely.

Iโ€™m talking about the deeply buried back-end bedrock, like COBOL systems or AS-400 applications. These are the quiet, invisible giants running our global financial institutions, municipal supply chains, airlines, and government agencies every single second of the day.

In those ecosystems, "the longer you wait, the worse it gets" takes on a terrifyingly literal meaning. It's not just that the codebase grows sprawling; it's that the pool of engineers who actually understand the business logic and syntax is literally aging out of the workforce. When a critical corporate ledger or transaction system relies on logic written in the 1970s or 80s, a migration isn't just a refactor; it's high-stakes digital archaeology where a single misstep can halt critical infrastructure.

It really puts the definition of a "legacy system" into perspective. Working on those deep back-end monoliths feels less like maintaining tech debt and more like defusing a bomb made of decades-old logic.

Have you ever had to bridge the gap between a modern front-end layer and one of these deep, ancient enterprise back-ends?

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

Thanks for this comment! And yes, I completely agree. The scale of some of these systems is truly mind-blowing.

Someone in the comments here mentioned that they once joined a COBOL project as an intern and discovered that part of the code had actually been written by their mother, who had long since retired. ๐Ÿ˜‚ That really puts things into perspective.

Personally, I've never had to build a frontend on top of a COBOL or AS/400 system, but I can absolutely imagine the challenges because I once worked with a Java backend that had originally been created as a proof of concept about 15 years earlier. Then the project kept growing and growing, and eventually people discovered that making even simple changes had become a nightmare. Adding a single form meant touching more than 80 files. ๐Ÿ˜‚

And I don't think that was necessarily because the original developers were incompetent (although, like in every project, that probably played some part). More likely, nobody expected the project to reach that scale when it started. There were discussions about fixing the architecture, maybe splitting it into microservices, but deadlines kept coming, priorities shifted, and eventually I moved on. I honestly don't know how that story ended.

Which, I guess, is exactly how legacy systems are born in the first place.ย 

Collapse
 
benjamin_nguyen_8ca6ff360 profile image
Benjamin Nguyen

I remember that I had a former friend where his father used to work with Cobol system.

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

Hahaha, from what I've heard, that's basically a gold mine these days. ๐Ÿ˜„

Collapse
 
benjamin_nguyen_8ca6ff360 profile image
Benjamin Nguyen

I mentioned COBOL to my father and he burst out laughing. He learned it back in the 1960s. Meanwhile, the Canadian government is finally moving away from those legacy systems and leaning into AI these days.

Thread Thread
 
sylwia-lask profile image
Sylwia Laskowska

Hahaha, I always say that if AI has made its way into government systems, then it's officially everywhere. ๐Ÿ˜„

Governments are usually among the most conservative organizations when it comes to technology, so when they start embracing AI, you know it's no longer just hype. The future has already arrived. ๐Ÿ˜‚

Thread Thread
 
benjamin_nguyen_8ca6ff360 profile image
Benjamin Nguyen

hahaha. Yeah, my current premier minister is huge in technology. He want to modernize the public civil serve and make productive like the private industry. He is a business man in most of his career.

Thread Thread
 
sylwia-lask profile image
Sylwia Laskowska

Hahaha, that's nice. ๐Ÿ˜„ Unfortunately, ours is more of a career politician. ๐Ÿ˜‚

Collapse
 
harsh2644 profile image
Harsh

Very Very Great Article Sylwia๐Ÿ˜‰ The longer you wait, the worse it gets this is the most honest truth in software We had a 2,000-line process() function that no one touched for years We called it The Heart of Darkness. When we finally had to change it, we learned more about the codebase in one week than in two years of avoiding it.

The code wasn't scary because it was complex. It was scary because we didn't understand it. And the only way to understand it was to touch it.

Thanks for the reminder. ๐Ÿ™Œ

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

Hahaha, I love "The Heart of Darkness"! ๐Ÿ˜„ Every legacy application seems to have one of those.

And you're absolutely right. Sooner or later, somebody has to touch it. The code itself usually isn't scary because it's inherently complex, but because nobody understands it anymore. And unfortunately, the only way to understand it is to dive in and start changing things.

Which is exactly why I'd rather do it sooner than later. ๐Ÿ˜‰

Collapse
 
chamikaravinda profile image
Chamika Ravinda

Few years ago I was involved in migrating a oracle forms app to a React app. It was a total mess. Before us one of the leading tech company has tried to do it and failed. We, the in house team started the migration on top of that code base. When I read this article I understand why it was a mess. Learned so many things that I shouldnt do in a migration, from that project.

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

Thank you! ๐Ÿ˜„ And that's exactly how I see it too. When it comes to architecture and migrations, I often catch myself realizing that people have already encountered most of these problems before us. There are patterns, best practices, and lessons learned, and it's usually much better to learn from other people's mistakes than from our own. ๐Ÿ˜‚

Of course, reality always finds ways to surprise us, but having those battle-tested ideas in the back of your mind makes things much easier. If my article helped you put some of those experiences into perspective, then I'm really happy to hear that. ๐Ÿ™‚

Collapse
 
pascal_cescato_692b7a8a20 profile image
Pascal CESCATO

Hey Sylwia!

When I read the title, I was already hooked โ€” which is hardly surprising... you've done it again. I absolutely loved your article; it captures the pain of a migration so well!

Personally, I hate migrations. Every single time, they turn into a nightmare โ€” regardless of how good the existing codebase is.

In fact, I recently completed one myself, both frontend and backend, and even for a relatively small application it took weeks of work. And that's without having to maintain two versions in parallel.

In my case, there was a v1, and the v2 introduced so many changes that the only thing worth keeping was the customer data; everything else had to be thrown away. I don't even want to imagine what an incremental migration would have looked like. Working on my own, I simply couldn't have pulled it off โ€” or what took weeks would probably have turned into months of transition.

Collapse
 
gamya_m profile image
Gamya

This really resonated โ€” especially the "temporary" adapter joke, because we all know temporary in software engineering means forever ๐Ÿ˜‚
The point about migrations being an iceberg is so accurate too. From the outside it always looks like "just upgrade the framework," and then you open the codebase and realize the real problem was never the framework itself โ€” it was the entire ecosystem that grew around it over the years.
The house renovation analogy at the end is perfect. The only truly bad strategy is doing nothing, and waiting until a production incident forces your hand. Saving this one for the next time I need to convince someone that migration debt is real. ๐ŸŒธ

Collapse
 
kansoldev profile image
Yahaya Oyinkansola • Edited

I think I prefer the big band approach because of how I am wired, it's even exactly the approach I am using now for a clients real estate website. I built it with pure PHP, and now want to rewrite the whole thing in Laravel in 2 months ๐Ÿ˜…, wish me luck ๐Ÿ˜ฉ. But it's good to know that refactoring too is a good choice, you can't just break your entire app if your business heavily depends on it.

Lovely article!

Collapse
 
technogamerz profile image
๐•‹๐•™๐•– ๐•ƒ๐•’๐•ซ๐•ช ๐”พ๐•š๐•ฃ๐•

This hits very close to home. I've worked on systems where the codebase was older than some of the developers maintaining it, and one thing I've learned is that legacy code rarely becomes a problem overnight. It grows silently while teams keep postponing improvements because there are always "more urgent" business priorities.

The real challenge isn't that legacy code existsโ€”every successful product eventually accumulates it. The challenge is when teams stop investing in understanding, documenting, and gradually improving it. What starts as a few shortcuts turns into fragile dependencies, outdated libraries, unclear business rules, and a codebase that everyone is afraid to touch.

I've seen situations where a simple feature request that should have taken a few hours ended up taking days because nobody fully understood the impact of changing one component. Every modification felt like defusing a bomb. At that point, the cost of avoiding refactoring became much higher than the cost of doing it. This aligns with the idea that delaying maintenance often makes the situation worse over time.

What makes legacy systems especially interesting is that they often contain years of business knowledge embedded in the code. Rewriting everything from scratch sounds attractive, but it can be incredibly risky. In many cases, incremental improvements, better test coverage, and continuous refactoring provide more value than a complete rewrite.

I've also noticed that younger developers sometimes view legacy code as "bad code," but after enough experience you realize that most legacy systems are simply the result of real-world constraints, deadlines, changing requirements, and business growth. Today's clean architecture can easily become tomorrow's legacy architecture.

The longer organizations wait, the more technical debt accumulates, onboarding becomes harder, delivery slows down, and developer frustration increases. That's why treating refactoring as an ongoing investment rather than a one-time project is so important.

Legacy code isn't the enemy. Ignoring it is. The best teams I've worked with weren't the ones with perfect codebasesโ€”they were the ones that continuously made their code a little better every time they touched it.