By Bruno Skvorc

Legacy Code is a Cancer

By Bruno Skvorc

It’s far too often that I see people shying away from newest technologies in the spirit of backwards compatibility. “We can’t move the minimum PHP requirement to 5.5 because we have 50% of our users on 5.4 still!”, they say. “There’s no way for us to move to Guzzle 4+, our back end is built on version 3 and it would take too much time and money”. I like the common argument from WordPress the best: “We can’t go full OOP and logic/presentation decoupling, because most of our users are running shared hosts with PHP 5.1 or don’t know OOP and/or MVC”.



Legacy Code – a big NO

This might come out controversial, but I firmly believe there is no room for legacy code in modern systems. Allow me to elaborate before you sharpen your pitchfork and light your torch. What I mean by that is: there should be absolutely zero reason to keep implementing the functions you’re adding to the new version retroactively into the old version, just because some people are still using it, even if the people using it are a vast majority.

To clarify: bugfixing legacy versions until their long term support contract runs out or you feel like it if you’re in charge, yes. Adding new features you think up for version X into version X-1 in order not to make the X-1 users mad, absolutely and 100% not. Likewise, adding X-1 code into version X just because it can “serve the purpose” should be illegal. If you’re still charging people for X-1 and basing your upgrades on that, your business plan is bad and you should feel bad.

Who am I to spout such nonsense, though, right? I’ve never had to maintain a large project with stakeholders and boards to please, a project that moves super slow and makes everyone happy as long as it works, no matter the fact that it could, potentially, work 100 times safer and 1000 times faster, right? Not exactly. My biggest baby was a big publisher site with a complex back end, built on ZF1. If you’ve ever done anything in ZF1, you know what a vortex of painful antipatterns it is. When the application started showing signs of deterioration due to increased traffic, I rebuilt the front end of the back end (the most heavily used part of the app) in its entirety on an ajax interface and API calls, lightening the load drastically and buying enough time to rebuild the entire suite of applications we had on the only thing the higher ups allowed – Zend Framework 2. If you’ve done anything on that, you know it’s a slightly less dense vortex of antipatterns, but still a vortex of antipatterns and bloat – but what I’m trying to say here is – huge upgrades and total rewrites can happen, if capable people are behind them. If all you’re doing are agile meetings and brainstorming, there’s no amount of LTS contracts that can stop you from looking stupid in five years.

Even if you’re doing free and/or open source work, you shouldn’t break your back for X-1 users, because you’re only doing them a favor by doing a major version increment, and with it, a major upgrade with a potential BC break. They should either adapt, or wither away.

So why should we exile legacy code from modern systems?

The Neverending LTS Curse

By taking the “support everything for as long as we can” approach, you’re burying yourself in a bottomless pit and looking at stretching yourself so thin several years down the line when you find yourself having to maintain four different versions, you’ll be banging your head into the wall wondering why you didn’t cut the V1 and V2 users loose when you still could have. In an attempt to maintain a bigger audience, developers often go out of their way to help users of past versions, for the sole purpose of keeping them around. This is also why WordPress is, in its current state, such an unfixable mess of amateur code. Don’t let yourself get chained to old versions.

These users are dead weight and should be discarded, no matter how much money they bring you. Give them methods of transition and move on – if they’re in any way capable, they’ll catch up in no time. If not, they’re not worth it.

By supporting older versions for too long, you enter the WP curse in which older versions, versions so bad they’re cringeworthy, require ever more manpower and effort to fix. This manpower is better spent building new versions and hiring developer advocates to help users transition.

You’re alienating and negatively affecting advanced users

The last time this desperate legacy grabbing affected me directly was while installing a CMS that proved particularly difficult to install in a Vagrant environment – not only due to symlink issues which are, by now, widely known (even to the creator of Vagrant), but due to them including a legacy version of the CMS inside the main CMS, because they share some installation properties, and the back end wasn’t fully rewritten into the new version yet. Why move onto a new version at all then? Why rush things if you’re clearly so far from ready?

By rushing the new version, they ended up with a sort of hybrid that’s neither here nor there – a Frankenstein’s monster of legacy code that still kind of works, but badly, and new code that has potential but cannot reach it without the mess that is the legacy code. While this approach does make the job of development companies who are still stuck in the 1990s easier, it makes the job of advanced users much, much harder. By catering to a crowd that should, by all logic, be extinct, you’re alienating and negatively affecting advanced users even more.

You know how it goes: don’t waste too much time trying to do the little details in legacy browsers. Nobody using those browsers will notice anyway. The same applies for users of libraries or content management systems – those who care about the legacy system won’t care about what you’re introducing into the new one, so you shouldn’t sweat blood over them more than necessary.

Failure sometimes ushers success

Of course, sometimes it just isn’t possible, and these exceptions are rare and valuable learning materials. One curious case of versioning and BC breaks is Python. Python is an awesome language. You can build almost anything in it. It won’t work as well as it could in a language built for that purpose, but that’s the nature of jack-of-all-trades types – they can do anything very well, just nothing flawlessly. When Python 3 came around, it introduced some BC breaks, preventing Python 2 users from a simple transition.

Most excuses were “There aren’t enough Py3 packages out there yet” and “We have too much code in Py2 to rewrite it all” – to which I say “Build what you need yourself” and “Poor programmers, being forced to program and all”, respectively. Granted, there were some valid arguments, and those tend to show up in projects that are so absurdly large, but the Py2 vs Py3 issue actually resulted in something else – the “Python Rift”. By the time Python 4 rolls around, the people who so vehemently refused to transition to version 3+ will still be stuck in Python 2 and the BC shift will become even greater for them. At that point, they might as well try and learn a new language. On the other hand, those who “braved the rift” and upgraded to 3+ without much hesitation, rewriting crucial modules themselves and adapting the language to their needs instead of the other way around will have a much easier time transitioning to newer versions.

This BC break effectively cut off the lazy and prepared the Python landscape for a new generation of developers. In my mind, that’s a success ushered by a version bump failure. Programming, like so many other walks of life, is still based on survival of the fittest – and if you can’t consume new technologies adequately, get out of the way for those who can.

Applications vs Libraries/Packages

There’s also the questions of apps vs libs. In other words, should the “no legacy” rule apply both to applications depending on, for example, frameworks that get a new release, or should this only apply to libraries in that they should cut ties with previous versions when new ones show up?

Both, in a way.

Libraries that get a version bump to X+1 should follow the clear path to progress – from the moment you have a publicly available new version, maintain a bugfix-only approach on the last one.

Applications that use such libraries are in a more difficult situation due to their logic depending on the APIs that may have changed. The sensible approach is to wait for stability reports from the community and, when verified, to begin the transition. During the transition period, both the old and the new version of the library/framework can remain in use, and once all necessary parts have been upgraded, the old version should be scrapped. Doesn’t this take a long time, though?

There is no web app big enough

“But Bruno, some apps are huge and would take months to be rewritten”, you might say. “Transitioning from ZF1 to ZF2 is a year’s work!”, to which I say: nonsense. There is no web application big enough to warrant that timeframe. In fact, I’ll go one step further and say that there’s no web application big enough to ever warrant using a big framework like Symfony or Zend.

No disrespect to either of those frameworks, they’re hyper complex behemoths of mostly professional code, but if you follow best practices, respect separation of concerns, encapsulate your services and APIfy your application so you can write front ends completely separate from back ends, there is absolutely nothing stopping you from doing full rewrites in under a month, regardless of the app’s size and/or popularity – provided your team mates are coders, and not theoreticians. It doesn’t matter how many patterns and algorithms you know about – you need to know how to use them to be effective enough to do transitions.

Upgrade Scheme

Which upgrade scheme should one use then? There is only one acceptable upgrade scheme any software developer should ever use, regardless of app/lib popularity:

  1. Introduce new branch for new version
  2. Mark the old version/branch as deprecated
  3. Publicly state how much life the old version has left
  4. Issue warning to all users of the old version
  5. Implement new features in the new branch ONLY, bugfix the old branch/version
  6. When EOL for old version, cut all ties. Don’t bugfix, don’t consult, don’t even reference it in docs. Kill it.

That’s it – following this procedure will let you never get into legacy trouble.

One project that adopted this approach in a way is Guzzle. They have a 3+ version, a 4+ version for those who can get with the rapid development of the 21st century, and a bleeding edge version for the daredevils who want the latest and greatest upgrades at all times.


As a web developer, I firmly believe legacy code should be abandoned in regards to new features on major version shifts. If you have a large project depending on software that’s moved up a version more than two months ago, you should stop all operations and rewrite everything to respect the new version – especially if the software you’re using is business critical. There is no application in the world big enough to need more than two months for a full transition, and if there is, it should be scrapped and written from scratch – the web is much simpler than all of us let on.

What do you think? Should legacy code be kept around indefinitely? A specific number of versions? Not at all? How do you feel about legacy code in third party projects used by a major project versus legacy code of those third party projects themselves? Do you feel there should be a difference in how either of those handles outdated code? Am I dead wrong here on all accounts? I’d love to have a good discussion about this – after all, my views and experiences are, obviously, my own. Let us know in the comments below.

  • Rob Galanakis

    You say “legacy code” but I think you mean “legacy versioning” (or maybe there is a better term). Generally when I hear “legacy code” it generally means poorly written unmaintained code, and/or code without tests.

    I can’t say I totally agree- I am a bit more forgiving on the “legacy versioning” issue- but I’m glad my post made was considered a “valid argument”! I will also note that “legacy code” and “legacy versioning” go hand-in-hand. If your code is thoroughly tested, it’s generally pretty easy to move up to newer versions.

    • Great to have you here, Rob, and thanks for chiming in! Legacy versioning may have been a better phrase, but I think the post as a whole drives the point home enough to explain the original phrase.

  • Intothe Middler

    Like Rob Galanakis I think the definitions and usage of legacy code here and all off. The article seems to jump back and forth too much and lost the point on myself. On a side note (and for how I was reading the article), we have hundreds of dealers, each of those have thousands of government users still being forced to use IE6 for purchasing. We’d have no way of “enforcing” anything on our dealers without them losing a whole bunch of their own customers. So it’s not always as clear cut anyway. Just because the author has worked at a few places, does not translate to this being a real world factor in being feasible to most, if many at all.

    • This post is mainly aimed at server-side stuff, but I see where you’re coming from. We’ve lost customers and traffic when we ditched old IE support, but this dip gradually auto-corrected itself.

      • Intothe Middler

        Only just seen this Bruno, but to say, our customers have their own customers who use our software. So trying to tell them that their sales may dip but auto-correct wouldn’t cut it. Many of them deal solely with UK government departments who will not be updating any time soon. So it’s not like they can wait for that to happen, or for us to go to our customer “sod your customers we want to update our code to alienate your current ones”. It just doesn’t make business sense to many. It’s okay your sales will dip for a while, but at least we’ll have new code – it pretty much what you’re trying to sell to customers/clients.

  • Hi. I’ve enjoyed many of your sitepoint articles. Thanks a lot for writing helpful stuff. This article got me curious. i have a large (140kloc, 120 database tables) ZF1 application that tried to do things the “zend framework” way: to deeply integrate with the framework and use its components as recommended by its manual as far as possible. The bulk of it was written 4 years ago. Now there are better ways: the PHP world has matured a lot in that time. Modern frameworks & ORMs will make a rewrite so much easier.

    I had to laugh when you said “there is nothing stopping you from doing full rewrites in a month”. I’d be interested to see you write an article on that: how to take a large legacy (old framework minimal unit tests) app and turn it into something modern and beautiful inside a month. From where I’m sitting now, it looks like well over a year for my gradual refactorings to tidy this monster up. I’m starting with the data model first: upgrade my brain to understand DDD (pluralsight courses!) then rewrite the persistence layer to use an ORM (probably Doctrine 2) and wrap it in a service layer so an API is possible (and mostly automatically generated). Thats my first several months. After hours I’ll be researching frameworks for the html UI and the API. Rewriting several hundred views into Twig will probably take 6-8 weeks if I don’t go crazy first, even with some in house tools to automate much of the boilerplate.

    Curious to see how you’d do this all in a month.

    • Like I said above, if it takes you longer than that, the project needs to be rebuilt from scratch, not transitioned. That’s the point – there’s no need for the superbloat. No need for Zend, no need for Doctrine. They’re great and interesting projects, but no current web app in the world is complex enough at its core to warrant their use – especially when you consider the performance hit they cause. Also, why Twig? Why process views on the server at all? Make your app API-based, and have someone else build the front end – that alone will take many months off your theoretical conversion, as long as you build the API well.

      • Dude, when I read this kind of threads, is when I would love to have Aptugo ready to roll and provide it as a serious alternative. I’m just a few months away to be able to tell steve: hey! you can do it in 10~15 minutes!

        • I’d love to take a look at that project if you’ll be taking on new closed beta users any time soon.

          • It really would be an honor. Please give me around 1 week to fix some stuff here and there and I’ll send you a message with creds.

          • Got it. Ping at bruno.skvorc at

          • Hey Bruno, sent you an email. Have a great day!

          • Bruno Škvorc

            Hey, saw it but didn’t get around to it yet! Will do soon!

        • I’d be keen for a look at that. Anything to avoid months of drudge. Our app is pretty boring: mostly CRUD with a bit of added salsa. The permissions system is pretty complex though with multiple roles and multiple custom constrains per role based on user attributes / date.

          • Well, I don’t want to take the focus out of Bruno’s amazing article here, so I’ll keep it short: I’m sure Aptugo could be of help, as it was actually conceived as a CRUD boilerplate then started to grow as a RAD. So, I figure that you could import your DB schema, create required relationships and build. Here’s a quick video on how it works by creating models (Sorry if I’m not clear enough, I’m struggling between the off topic of the conversation and the will to try to be of some help here!) But please, feel free to contact me!

          • Looks interesting. Reminds me of Phreeze:

          • Ha! I wish I would have known about Phreeze a couple of years ago. And yes, basically from what I saw in the video, the quick web app generation looks really similar! thanks!

          • Hey Steve…I’m thinking right now, I’m not sure Aptugo would be great for you at this stage (the models/database screen would be really crowded with 120 tables, I’m hoping to rebuild that screen as soon as I can pay a graphic designer) of course you’re more than welcome to give it a go. Please contact me at gaston at so we can talk there. Enjoy! G

      • Bruno, is there an article (or can you write one) on how to APIfy a full application like that?

        There are several on how to build a REST API or what else for publishing a service, but I’d love to see one on how to make a full application API-based.

        • Translating an existing app into an API is not an easy task and depends on the framework that’s in use. Oftentimes, frameworks add unnecessary bloat to the API requests because they fire up templating engines and whatnot inadvertently, when all you need is an API token checker and a quick responder.

          I would suggest you build an entirely new API-only app on the same data set the original app uses, and gradually phase out the old app as a new frontend which targets the new API is developed.

          There are super fast frameworks dedicated to API-only approaches, and when engaging in these endeavors, you should utilize them. One such example is Phalcon, the current performance champion among frameworks. See here:

      • West

        Joel Spolsky says that you should never rewrite your code from scratch, here’s his article: and here looks like what you should do instead of rewriting code from scratch:

  • jokeyrhyme

    Great article, as usual. :)

    • Cheers!

    • AnneDTownsend

      $9­­­­­­­­­7­­­­­­­­­/­­­­­­­­­h­­­­­­­­­r­­­­­­­­­ re­­­­ceiveing­­­­­­­­­­­­­>>>CLICK NEXT TAB FOR MORE INFO AND HELP

  • Toby Bettridge

    I’m starting to think that you need to spend some time working how to get data out of a new system you’re building in a usable form so when the time comes to upgrade from one major version to the next you can do it properly and not worry about the migration or alternatively not be locked in to the same CMS next time.

    Particularly, in the latter case, where the CMS has third-party plugins that effectively rot between versions with no upgrade path.

  • Michael

    “there’s no web application big enough to ever warrant using a big framework like Symfony or Zend” and “there is absolutely nothing stopping you from doing full rewrites in under a month, regardless of the app’s size and/or popularity”.

    Really?! So what you’re saying is basically, that you should never use any of these frameworks?
    Any app big enough to warrant Phalcon and a separate language, Zephir?

    Also: What do you specifically mean by “full rewrite”? Same framework/libraries or different ones? How many people do you need to have the “guarantee” do get it done in under a month. You put it like it doesn’t matter…

    Oh, and I think you should be a little more accurate in how you portrait Symfony. It is also a framework, but it’s – I think – even more so just a few components that you can assemble yourself. No one forces you to use forms, Doctrine or Twig. I think the HTTP framework in particular is really good and speeds up dev quite a bit.

    That said, I agree with your general attitude regarding supporting legacy code. Bug fixes, and nothing else. Always keep moving.

    • I don’t say you shouldn’t use them, I just say they’re not necessary if the app’s components are built well and compartmentalized enough. I really don’t have anything against any of these frameworks, really, and yes, the same argument applies to Phalcon. I prefer it simply due to the fact that it’s so much faster than others, and if I have to resort to a framework I’d rather pick that one, is all.

      Under full rewrite, I mean back to the drawing board, plan your app from scratch. Obviously something is wrong if you can’t upgrade it easily. Whether on the same framework/libs is irrelevant, it’s the architecture that matters. Number of people depends entirely on the complexity of the app and the quality of those people.

  • Great article !

    However I think sometimes it’s very complex and too much time consuming to rewrite an application entirely.
    For example : I’m working on an application with a very complex back office. For two years project’s specifications have been changing all the time. Many different developers coded on it. For the most of them, it was bad developers : huge switches and code redundancy everywhere.

    I’m working on it since 6 month and I’m alone. My deadlines are very very short. How can I possibly think of rewriting the entire project ?

    It’s a very good article but I think there are exceptions.

    • That’s a very difficult situation to be in – it happened to me too. Inheriting a horrible project is never easy, and it’s much simpler to write it from scratch than to keep it up to date.

      • My deadlines don’t allow that and my company either.

        Building from scratch is great but I prefer using framework for the sake of developers who will work on the project. I think it’s better to use tools that people know and understand but you’re right on the ‘dark sides’ of this kind of solutions.

        • Of course, I’m not against frameworks. I’m against using them badly. In the ZF1 project I mentioned in the post, I’ve often seen 1000+ lines controllers and models spanning multiple databases, not just entities.

  • Joeri Sebrechts

    Sane advice, but there is a migration cost associated with upgrading a codebase as well. For example, the codebase I work on is 500.000 lines of code. It uses ZF1, but not extensively (only Zend_Db, Zend_Mail, Zend_Validate and Zend_Json_Server). I took a look at the ZF2 upgrade. It does not improve our ability to deliver features, it merely changes the flavor of the API. So, I concluded there was simply no reason to upgrade at this time. Whatever bug we run into in ZF1, we can fix it easily (and that hasn’t happened in 2 years).

    I think your notion that there is no codebase large enough to warrant a framework like Symfony or Zend is right and possibly wrong at the same time. You’re right that buying into the large MVC architectures that those frameworks provide is unnecessary if you have a javascript-based UI and only implement web services on the server. Our UI is javascript-based, and the server code is pretty light-weight. You’re wrong (in my opinion) if you say those frameworks shouldn’t be used at all. They offer a lot of value when you use pieces of it, like we do with ZF. If you use multiple libraries to handle different responsibilities like DB integration, mail sending, web services, data validation, … you end up with an inconsistent codebase with a lot of dependencies. Better to have one big easy to track dependency than a dozen smaller ones.

    • I guess I should have phrased it differently – I’m in no way saying you should completely avoid those frameworks. I’m just saying I don’t see a direct need for them if the app is built well enough and if its parts and services are properly compartmentalized. Of course you should use any framework (and component) you see fit.

      • “I’m just saying I don’t see a direct need for them if the app is built well enough…”

        I think you’re just digging the hole deeper. No app under a MVC architecture can be “well-built”?

        • Not sure where you’re getting that. I’m not anti-framework or anti-mvc, I’m pro-structure and pro-encapsulation. If you have well built services, it literally makes zero difference which framework you’re using.

  • gggeek

    “if it aint broken, don’t fix it”.

    Can’t honestly say I agree with the premises or conclusions of this article.
    The approach you seem to advocate is to always follow the latest fads, without thinking about the cost of rewriting, nor its usefulness (neither topic is, after all, discussed in depth). But doesn’t all code after all serve just a business purpose?

    In my experience all good developers do love playing with shiny new toys. Which means that they can immediately and fully adhere to the idea that “doing it with a new pattern/library/methodology/framework/tool” is good.

    Otoh it takes a lot of experience to admit that code rot happens in every single project, just because of real life: changing/incomplete/conflicting specs. political decisions. time/cost pressure. etc. etc. And in hindsight, you always could have done it right the first time.
    But have you ever heard about the “second system syndrome”? By the time you finish the v2 of your app, there are great chances that it will contain a complete new sets of bugs and brokenness, just not the same as the v1.

    I am not against good patterns and code quality. In fact I am pretty much against the “throw everything at the wall and see what sticks” mentality that bad TDD evangelism seems to have encouraged for years.

    You can look at MS APIs as a good example of where the “rewrite everything every six months” approach goes wrong. This makes life a huge pain for both the developers using those APIs and the end users of the applications. But hey, directX cant make you less productive than GDI, can it? In front you have linux which kept using the same old POSIX stuff for ages, and did quite well with it.

    In other words: “new” != “better”.

    The point of the article I agree more with is in fact the “you do not need a framework”. I would go even further and say: you probably do not need a lot of patterns.

    Build a thorough understanding of the business needs, and spend some time figuring out a solid model for the case at hand. Separate cleanly everything into layers. Make sure you can explain your architecture to both a dev guru and a businessman.
    Then start coding.
    Then refactor your architecture twice.
    Then you win

    • Great insight, thanks for chiming in! I’m not necessarily advocating for a “newest shiniest” approach, it makes no sense just to upgrade for the sake of upgrading – I’m mostly against keeping old versions alive alongside new ones. When new versions appear, they should absolutely destroy old ones is what I’m trying to say.

      • Bill H

        In some cases, I agree, but those are the exceptions, not the rule. I’ve worked on multiple code bases over 30 years that took hundreds, and once even thousands, of person-years to develop. Some were single-user applications, others were large enterprise applications. I suggest your experience with web development doesn’t reflect the world of large software. Code rot is an issue, but projects targeting specific subsystems makes more sense than to start from scratch.

        And, your idea of dropping features from customers loses customers. That happens even to companies that are growing. Read the book, “Crossing the Chasm” and you’ll get a better idea about why what you suggest is typically not good advice.

      • gggeek

        Ok, sorry for going a bit offtopic.

        About the specifics of keeping-old-versions-alongside-new-ones: I guess the general answer is “it depends”, as for everything.

        The cost-of-maintaining compatibility will generally increase over time, as the codebase caters to more and more requirements and adds support for different environments/platform versions and all the quirks in each revision of those.
        At some point, the rewrite will start to make sense, as it will be cheaper than doing maintenance, and should be attempted.

        So you say that when creating version X, only bugfixes should go into version X-1.
        But this also has a cost: as soon as I split, I have to maintain 2 codebases and test them separately. What if on the other hand version X is fully backwards compatible? Then all customers are encouraged to upgrade, and I can maintain a single codebase, saving time and money.

        Someone else mentioned “contempt for the end user” in a comment.
        Without going so far, I can also testify that as a user of dev tools, operating systems and code libraries, I am greatly suffering of a burn-all-bridges mentality. Say that I want to add feature A to an app. That feature is only available in version X of the std library for the platform. And version X requires the latest version Y of the DB, which only runs on version Z of the operating system, which requires hardware W. And guess what? My app uses library X-1, database Y-2, operating system Z-3, running on hardware W-4. So now I am left with the options to either implement the feature by myself, wasting time and introducing more bugs than the public version probably has, or spend a lot of money (and time) to upgrade the whole stack.

        • Your example is valid, albeit extreme. I don’t think there is a web app complex enough out there, not even in concept form, that would be based on PHP and would require specific versions of hardware and/or OS. If such specificity is required, you’re better off building it as a separate app with a consumable API.

          • gggeek

            Just to be clear: in my example it’s not the php app which needs a specific hardware version. It is pretty much the opposite: the app is hw independent, but the chain of dependencies on specific versions (because backwards compatibilty was not maintained) forces the app developer to do an hw upgrade.

            As for web apps branching out to the OS: two words: exec() and com

    • flynismo

      While newer does not always mean better, I do not think it is
      responsible to (inadvertently or intentionally) lock your customers into
      a code base that is difficult or impossible to upgrade efficiently. I
      believe that is what Bruno was getting at when he said that if it takes
      that long to rewrite, then the developer did not know what they were
      doing (or were lazy). Honestly, writing modular code takes very little
      extra time as compared to legacy, tightly coupled spaghetti….it does
      however, force proper planning before writing a line of code, and when
      rewrites start becoming very difficult, it seperates the wheat from the
      chaff — we quickly see who looked at the bigger picture, and who just
      wanted to get the project done with ASAP and make a buck.
      Also, “if
      it aint broken, don’t fix it” — eventually all code breaks, as the
      language evolves. It is again, a matter of writing maintainable code.

    • Carlos Osuna

      Excellent post I tweeted your response to my followers.

      BTW. If you follow AMCs “Halt and Catch Fire” you clearly see both paradigms reflected on the two protagonists.

      On one side, the IBM deserter and chief salesman, Joe MacMillan,has a Microsoft type mentality. “Change everything, so we can amaze everyone”.

      On the other hand, the ex-mainframe specialist whose microcomputer went wrong, Gordon Clark, has a Unix/Linux like mentality. “Let’s finish what we have accomplish, cutback if we need to, so we can deliver.”

      Either one has a problem.

      The first one has too much vision and everything he releases will be incomplete, just like what happened to Microsoft, until it fell off the ledge with Vista, just to repeat the exercise with Windows 8.

      The other, know not where to go next, which basically plagued desktop Linux for a while, just copying Microsoft and Mac with whatever they invented. It took Guts and Google to basically fix this with the mobile and Android.

      In the end, there’s no magic place and no magic approach. Every customer is different and every project demands it’s own compromises and risks.

      Just my two cents.

  • Le Pixel Solitaire

    When my company will be big enough to let go major customers like some Canadian government agencies who are asking to be IE6 compatible, I will gladly ignore those revenues just because I don’t want to develop «legacy code». So if you have plenty of these kind of customers please send them to me, I will be more than happy doing business with them.

  • M S

    And 15 years later….

  • Refactor All the Way!

    I’m completely with you Bruno!

    I worked on a behemoth project that spanned across multiple front-ends, which took around 5 years to build. By the time i got involved the project was suffocating itself under bad code and old stuff.

    I managed after many many reunions and brainstormings to make other people there see that a full rewriting was in order.
    With only me and another co-worker, we rebuilt that 5 year project in under 8 months fully testes and with a bunch of new features. This said, the number of daily operation before this re-factor was around 500 (in peak days), this number was raised to around 5k (there have been way higher days).

    It was a high risk yes, but the risk of staying old was even higher. A lot of good stuff can really be done quickly if you take time to think on it before, which many don’t do, just code away then projects becomes huge with no apparent reason.

    On a final note, let me just add that when a developer makes this kind of work, you really learn a lot about what new stuff is out there and increase your skills by a lot. Don’t be afraid to rewrite that code folks! Fear is what is stopping our world from being great!

  • a8521298

    “the Drupal/WP curse” Is it fair to lump Drupal in that category? Each major Drupal release is not backwards compatible — intentionally so, in order to make major strides forward.

  • Wonderful post. It totally echoes my own thoughts on both the big frameworks, and supporting ‘old’ software. I have fallen into the trap of trying to tweak some ‘legacy’ in-production code made by an ex-employee several years earlier and thinking “It’ll be quicker to hack this together with what’s there than rewrite it”. It usually takes just as long, or worse, introduces bugs into completely alien parts of the system because they’re indirectly sharing some of the code due to poor separation of concerns.

    That said it only becomes an issue when the code needs to be changed, if it’s running and working there’s no reason to rewrite/update it. However, once you need to work with it, in the end, hacking stuff into already poorly written code is more difficult and becomes a growing maintenance problem. After years of experience on multiple projects for various companies, I have to say the best (and almost always, overall, fastest) way of working with code that is ‘difficult to work with’ is to rewrite it.

    ‘Difficult to work with’ is, of course, subjective and defining that is what I’m currently looking into as part of my PhD :)

    • “That said it only becomes an issue when the code needs to be changed, if it’s running and working there’s no reason to rewrite/update it. However, once you need to work with it, in the end, hacking stuff into already poorly written code is more difficult and becomes a growing maintenance problem. ”

      Exactly that, thank you!

    • “After years of experience on multiple projects for various companies, I have to say the best (and almost always, overall, fastest) way of working with code that is ‘difficult to work with’ is to rewrite it.”

      Hate to say it, but I when I hear something like this my first thought is that the developer saying it is simply too lazy to dig into the code base and determine just why it was written the way it was written.

      Not to mention that it’s “almost always” more difficult to rewrite that you think it is.

      You have to dig out all of the business rules and logic and reimplement them, and then you have to regression test the entire application to make sure you didn’t blow something up, and then you need to track down and fix all of the new bugs you added to the app, since no one writes perfect code.

      • The problem is, that when you don’t know all the business rules and logic making changes becomes like spinning plates. Especially when you don’t know where code/global state is reused. While you can hack something in that works, more often than not with badly designed code, it creates action at a distance so then you end up getting a call to fix something else that was working fine.

        The biggest issue is a future maintenance one. it will always take longer to make further updates so there’s going to be a trade-off between how much time you spend rewriting something vs how much time you spend trying to fight with what’s already there.

        A good example I had recently is an old product management script that required nearly a dozen edits to add a single field to a form/database, including several long (25-30 argument) sprintf() statements for the queries, whereas in a modern system it’s a matter of one edit to a .xml file or similar. After doing it 3-4 times over the course of a year and having to spend a fair amount of time making sure I didn’t miss any of the occurrences, the next time I spent an hour or two rewriting it, and now the entire script is far more manageable.

        You have to spend time digging out all the business logic anyway or making changes to the code inevitably introduces new bugs/issues. On more than one occasion I’ve been asked to make a change to something in a large system, made the change and then had the client come back with either “but it’s not showing on [this other page that does something similar that I didn’t tell you even existed]” or “Wait! It’s not supposed to be showing to people who log in to this special login area you didn’t know about!”. Whatever you do you either need to carefully comb the entire application for potential knock-on-effects or risk introducing new problems.

        Of course the underlying issue with most of these problems is poorly documented code, unfortunately, poorly documented code is most of the code that exists in the world.

        • If you spent “an hour or two rewriting it”, then it’s not quite the major system being discussed above. Regardless, you rewrote it, hoping that the rewrite wouldn’t cause additional side effects, hoping you caught all of the business logic, and hoping that you didn’t introduce new bugs.

          Further, if you just spent “an hour or two rewriting it”, then your code is now likely to be the “poorly documented code”, and I suspect that the next person who’s assigned to fix it or extend it will, like you, shake their head, wonder what the other guy was smoking, and select File > New from the menu.

          It doesn’t seem like you or Bruno have spent time in major financial, medical, aviation, or engineering systems that are truly massive projects and that require planning, reviews, meetings, and adherence to many, many, many Federal rules and regulations regarding security, privacy, and code worthiness.

          • That was one instance that was easy to explain because it was small, however I wasn’t talking about rewriting the entire system, and I assume Bruno wasn’t either. I meant rewriting the problematic part of the code any anything directly connected to it.

            One would hope those projects would be properly documented so not require traipsing around hundreds of files trying to understand where something happens, unfortunately in the real world, when you get burdened with a project you haven’t been involved with previously, in the rare instance there is any kind of documentation beyond a simple API (that I can see from the classes anyway) it’s usually out of date or was put together at the design stage and not updated during the development process.

            It may be better in some industries than others, but for most projects I’ve worked on (One of which was a large company that ran the entire business through the website which consisted of scripts to deal with a 400gb+ database consisting of hundreds of tables and billions of records) documentation was sparse and trying to work around poorly implemented 8 year old code that was written by someone who had left the company three years earlier then hacked around by someone else so you don’t even know which parts are used any more… it’s easier and less time consuming to re-evaluate the requirements and rebuild it.

            You’re right that’s is a mixture of a management, documentation and requirements engineering issue, and I agree that is the root cause of all these problems. But in business the bosses want things done yesterday and stuff gets hacked together and then you or I come along years later and need to work with the code. Poorly documented, poorly implemented legacy code does exist, and in large amounts. Saying “Rules/regulations/planning/documentation should prevent it” is idealistic and while true in most cases, doesn’t give a clear indication of the state of code that’s actually out there in the wild.

  • Miguel

    “This is also why WordPress is, in its current state, such an unfixable mess of amateur code.”

    I work with WordPress and I agree with the sentiment. I often ask myself “why do I keep working with it”, and then I remember, “oh yes, there is a bunch of clients willing to pay for WordPress programming services”.

    • Not to sound insensitive, but there’s a lot of fiends looking for a heroin fix too, giving their last dime for it. Doesn’t mean we should take advantage of them. Yes, I went there. I compared WP with heroin.

  • Dan

    No one likes old code, no one likes working with it or serving it. This is possibly the most self-absorbed arrogant article I’ve read on sitepoint.

    “These users are dead weight and should be discarded, no matter how much money they bring you.” – Have you never worked in a real world business where you’re the stakeholder?

    • I was never a stakeholder in a business which employs me, no. If I was, I don’t think I would have easily let it get to the point in which we need to think about full rewrites.

  • Cheers!

  • i disagree with you on how you use the word legacy, the common use is bad legacy, but the interesting and good part in legacy exists meaning those transitions are possible for the experienced architect ;)

    • another note is the use of the word cancer, i think you have to be more careful in using the word as it can wound more than one reader that may have a scarce with this disease. Please be more careful.

  • Michal Zahradníček

    This must be carved in stone!!!
    Thanks for great article.

  • Larry Kagan

    Well Bruno, you certainly initiated a response from your readership! While I think your views are a bit heavy-handed, this article certainly got many people thinking… and isn’t that the point? Hopefully your words are, at the very least, a motivator for us devs to put a greater emphasis on upgrading the core of our systems instead of “hacks” to make them work. Kudos amigo, keep up the good work.

    • Thanks! That was the point – a decent discussion on the matters. Not everyone might agree, but it was definitely interesting to find out what everyone thinks and how people approach these issues.

  • Peter Tasker

    I think one of the things this article misses is the ‘business’ side of things. Try and tell management you want to spend a month (at best) to refactor a functioning app.

    While I agree that code should be refactored, at some point you have to step and back and ask yourself as a developer “is this worth it”.

    I’ve seen plenty of really good programmers waster YEARS refactoring projects, and for what? A code base that is easier to maintain?

    There’s definitely times when old code should be rewritten, but I’d keep in mind the business case for such efforts.

    Also, WP powers what, 20% of the internet? Seems like legacy “written by amateurs” will be around for some time.

    • “Seems like legacy “written by amateurs” will be around for some time.”
      Oh no doubt, a sad truth.

      Of course, one shouldn’t refactor when things work. But when time comes to make a solid change, rather than alter a 10 year old codebase to make it happen, I would always argue for a rebuild – and there isn’t a management team or CEO in the world which I couldn’t convince that that’s not a saner approach.

      • Mike McCarthy

        Well that’s the rub.
        ‘Of course, one shouldn’t refactor when things work. But when time comes to make a solid change, rather than alter a 10 year old codebase to make it happen’
        That’s a business decision at companies with succesful applications. The business folks have different motivations.. It may make sense to them to just throw bodies at maintaining old code.

        Customers don’t care about the quality of the software engineering. Just whether the application works.

        • Tony Marston

          I agree entirely. Scrapping old code that works just to make it “new” and “shiny” is committing commercial suicide. Asking the customer to spend money on a rewrite which does not produce tangible benefits for him is one way of joining the dole queue. The only time a rewrite can be justified is if you cannot add essential new features to an existing code base because it was badly written in the first place, or badly maintained since, and it is quicker to rewrite it instead of patch it.
          I work with code that I started writing 12 years ago, and it is still going strong. Why is this? The original design was simple and sound, and all enhancements have been added in such a way as to maintain backwards compatibility. The code may be old, but it does what the customers want and are willing to pay for, and it is regularly enhanced to provide new features.
          If it ain’t broke, don’t fix it.

  • Debiprasad Ghosh

    Brahmacharya(student life): What should be the new features.
    Grihastha(household life): Money making
    Vanaprastha(retired life): Bug fixing, but connected
    Sannyasa(renounced life) Disconnected (Open source)

  • I claim that there is no such thing as “large software” in web development. There is no web application to warrant that much work – if someone did work that long on a web app, they didn’t know what they were doing.

    • Tony Marston

      There speaks someone who has never worked on a large business application, such as one that uses
      over 250 database tables with 450 relationships, and has over 2,000 user

      • Actually, I have.

        • Tony Marston

          Then it must have been a toy application as anyone who claims that they can rewrite an application of that magnitude in 3 months or less just doesn’t know what he’s talking about..

    • Tarabass

      This is such nonsense. I’ve worked, and am working, on several portals that are big ass software applications. If you want to be independent you can’t just call some libraries which are ‘hot’ in the community. At the moment we are building non-stop with 30 people on a portal, where end-users can create their own modules and databases, screens and workflows. Don’t end up saying there are no large software applications because you didn’t see them. There is more than just some discussion boards, blogs and photo galleries hanging together with some ‘latest and greatest’ javascript libraries..

      • Bruno Škvorc

        Who said anything about JS libs? I’m talking PHP here.

  • “By taking the “support everything for as long as we can” approach, you’re burying yourself in a bottomless pit ”

    Your mindset is just as extreme as this mindset, it’s just on the opposite end of the spectrum.

  • Tony Marston

    This article was obviously written by someone who is either incredibly naïve or has only worked on tiny applications. The idea that you must constantly rewrite your code to make use of the latest technologies, fads and fashions just will not work in the real world. Customers don’t care about how the code was written, just that it works. It has to fulfil its task in a cost-effective manner, and asking the customer to pay for a total rewrite without any tangible benefit for them would be commercial suicide.

    Having said that customers don’t care how the code was written is not an excuse to produce any old crap and say “It works, so who cares?” All code should be properly designed and implemented, but always remember that code that is “good enough” which can be shipped today will always be worth more than code that is “perfect” that will not be shipped until some unspecified date in the future. The problem with “perfect” is that it cannot be defined in a way that satisfies everybody. “One man’s meat is another man’s poison” is an old saying, which can be updated to “One man’s ‘perfect’ is another man’s ‘putrid’”.

    I do not design and build public-facing web sites, only business-facing web applications. I switched to PHP in 2002 after several decades with other languages, and the first thing I did was to rewrite the framework that I had built and used in those previous languages. I didn’t use any existing PHP framework for the simple reason that in 2002 there weren’t any, or none that did anything near what I wanted. I released this framework as open source in 2006 and it is still being maintained and enhanced today. In 2007 I used it to write a major business application which again is still being enhanced and still attracting customers today. It uses over 250 database tables with 450 relationships, and has over 2,000 user transactions. The idea that such an application can be totally rewritten within a month can only be put forward by someone who has never worked on real applications in the real world.

    My code was written in PHP4, and although everyone now uses PHP5 I only updated the code to the PHP5 way when it was absolutely necessary. Because the original design was simple and sound it has been very easy to
    enhance it to provide new features, so it does not suffer from a tangled code base that is difficult to work with. The latest version will also run applications that were built for the original version, so it provides complete backwards
    compatibility. Those modern framework developers who cannot maintain backwards compatibility should hang their heads in shame. If they had got their design and implementation right in the first place then they wouldn’t have produced a mess that needed a total rewrite.

    The idea that as soon as a new version of PHP is released with new features or capabilities that every developer should rewrite his code to make use of these new features is not one that I am willing to follow. I have code that I wrote 12 years ago that could be rewritten differently, but it still runs in the latest version of PHP, so why bother? If it ain’t broke, don’t fix it. If the cost of the rewrite cannot be balanced with tangible benefits to my paying customers, then they will not be willing to pay for it, so any effort spent will be effort wasted. I would much rather spend my time in writing code, or even adding to my 12 year old code, if it earns me money by satisfying my

    Saying that there is no room for legacy code in modern systems is the wrong attitude. The term “legacy code” is often taken to mean “code that does not conform to modern practices”, but I’m afraid that some of these modern practices are nothing more than gilding on a turd. It is badly written and unmaintainable code which causes problems, not old code. Old code is not necessarily bad just as new code is not necessarily good. I would much rather work with 12 year old code that was well written instead of some of this modern crap which is overloaded with too many design patterns.

    The primary purpose of a software developer should be to develop cost-effective software which satisfies the paying customer, not which wins praise from your fellow developers. If I can write an effective piece of software in 500 lines of code using “old fashioned” techniques then this has more value to the paying customer than one written using “new fangled” techniques which requires 1,000 lines of code.

    Legacy code is not the problem. Unmaintainable code written by bad developers is.

    • I’ve worked on a system of the magnitude you specify, and have rewritten it from scratch. I claim that I would be able to rewrite your entire PHP4 application in three months in modern PHP, on my own.

      I’m not saying you should jump on the “new fad” bandwagon as soon as a new version or approach of anything appears. What I’m arguing against in this post is having both a living legacy version and a living modern version of your app/lib. To name a specific example, see the eZ Publish post I link to in the article. That CMS has an ancient version inside the new version, and this causes such an inefficiency it effectively hinders people from not only using it, but also installing it.

      To be clear – I absolutely agree with “if it ain’t broke, don’t fix it”. If the code works as expected and is built in such a way that any new developer can take over development without looking through a yarn of spaghetti code, definitely. If you can introduce new business critical updates in a matter of hours without breaking anything at all, perfect! Write it in analog binary with black and white stones for all I care. But when you get to the point where you have two codebases and maintain each for the sake of pleasing the people who refuse to upgrade (or who don’t know how and refuse to learn, like many do with Composer and OO PHP these days), then you should cut all ties with the past and *force* them to do so.

      • Tony Marston

        If you think that you can rewrite my entire ERP application in 3 months or less then you simply don’t know what you are talking about.
        I certainly don’t have a legacy version and a modern version of this application. I have a single version that was written in PHP4 and still runs under the latest version of PHP5. The only changes I made to the code were those that were absolutely necessary, such as the switch to different extensions for processing XML and XSLT. The code was well written to begin with, and has been well maintained, so it is definitely not a huge pile of spaghetti code. Because I refuse to rewrite working code to conform the idealistic “PHP5” way or the “proper OO” way I have also not morphed it into a pile of ravioli code.

        • After all your irrationally insulting comments, I suppose there’s nothing I can say to you any more other than – let’s just agree to disagree and say that we consider each other clueless.

          • Tony Marston

            You are the one who made the claim that “there is absolutely nothing stopping you from doing full rewrites in under a month, regardless of the app’s size and/or popularity” I merely pointed out that there are some applications out there which are much larger than those you have worked on and which would take much, much more than a month to redevelop. If you do not believe that such applications exist ten it is your experience which is lacking, not mine.

          • Bruno Škvorc

            I’ll believe there are such apps when I see them. If 100000+ files with 15GB of constantly accessed data isn’t a super large app, I don’t know what is. And if there is something bigger, it probably wasn’t built well.

            When rebuilt from ZF1’s mess of 100k files, the ZF2 version had less than 1000 files, and twice as much functionality. It’s being maintained and upgraded to this day, and new features are implemented the very same day they’re requested, as opposed to weeks later as it was before.

          • Tony Marston

            “I’ll believe there are such apps when I see them” means that just because you have not seen some of the very large applications that exist in the real world you imply that they simply don’t exist.
            By “large application” I do not mean that it has large volumes of code, as you have said yourself that you took a “large” ZF1 application and rewrote it into a smaller ZF2 application. That just tells me that it was a small application to begin with that was badly written in the first place.
            To me a “large” application is one which has 2000+ user transactions, not 2000+ files on disk. A ZF1 application may require 100 files to do what I can with just 10 in my application, but that does not mean that the ZF1 application is bigger (ie: it does more) it just means that it was badly written.
            I am the author of an ERP application which took 5 man years to build, so the notion that you or anyone else can rewrite the whole thing in one month just won’t wash..

          • Bruno Škvorc

            To pull a parallel example, you’re a religious person who saw a miracle and is trying to explain it to an atheist. Show me, and I’ll believe you.

            The app I mention did have similar traffic, but was also a code mess, yes. The fact that you needed 5 years to build an app, does not mean everyone would take the same time.

          • Tony Marston

            If I had used the Zend framework it would have taken 2 or 3 times longer.

          • Bruno Škvorc

            No doubt.

  • DampfLokomotiv

    Hello Bruno, thank you for sharing your

    First of all, your brain (and,
    coincidentally, my brain also) IS legacy. Millions of years of
    evolutions has made this “computer” what it is now.. even
    enabling me to react on your blog :o) Millions of neurons and
    synapses combine in to what can be conceived as networked associative
    intelligent logic.. Many parts of our brains/DNA represent still the
    very same logic building blocks instated millions of years ago.
    Impressive. Although our thinking centers are continuously updating,
    the nucleus is an incredible amount of legacy code, is it not?

    Anyway, more to the point:

    Simplified, the very essence: (also in

    1. if things work ok, don’t change

    2. make new things in such a way that
    they harmonize with already existing things.

    I have been working for many years in
    IT, most of the time designing and building IBM Mainframe application
    programs, using COBOL, PL/1, DB2 DL/1, etc. Typically, mainframes are
    used by large companies. Most of these companies have a software
    environment with literally thousands of programs and very complex
    relational databases with hundreds (if not more) of database tables.
    Also, there are often still many sequential and indexed (e.g. VSAM)
    files. Many programs written even more that thirty years ago are
    still in use because there simply is no reason to rewrite them. So,
    this is legacy. Of course, over the years things tend to become very
    complicated, and often even chaotic, any mainframe programmer can
    tell you that. However, It would be an incredible daunting task,
    costing an enormous amount of money, to convert everything to newer

    That is the reason, large companies,
    e.g. banks, insurance companies, stock exchanges, still mainly depend
    on legacy mainframe software. (For example, if you are doing bank
    transactions in an internet browser you are looking at a relatively
    thin web front-end client. The real work is done on these legacy

    In this context, that is, for this
    very large hybrid software systems, deprecation would be impossible,
    fatal. It would mean that most programs would have to be rewritten.
    It would need many years to do that. Not even mentioning testing this
    metamorphose. Forget it, not practical.

    Although I consider your “Upgrade
    Scheme” as logically sound, it extremely difficult to deploy
    this method in very large legacy systems because mostly, there are
    seldom well defined separable branches/structures in these
    environments apparent, because through all the years of its existence
    and evolutions everything is hopelessly intangible intertwined..

    About deprecation itself: currently I
    am also working with newer technologies like iOS iPad app
    development, which I really like. From time to time things get
    deprecated. This is one of the biggest and costliest troubles in
    modern software development. This is awful and, as I see it,
    completely unnecessary. I have to get back to solid working code,
    many years flawlessly active, change and test it again. Why? As a
    contrast: most mainframe software written in say,1976, works without
    any source code modification perfectly on today’s mainframe systems.

    Of course new development is excellent,
    allowing us to write very advanced and more user friendly
    applications. However, no language elements should be deprecated, but
    just tagged as “not recommended”. So, this would mean that
    the > 100 programs you might have written in this year don’t need
    to be unnecessarily modified.. that frees up time to use newer
    features coming available to even write better software

    I have also been involved in web
    application programming. Now that is really chaos, with a myriad of
    languages, tools, services. and they change all the time…

    About WordPress: as a WordPress user i
    am very happy with it, as it is very easy to create and maintain a
    website, I find it very useful for my iPad apps. From this
    perspective, as a user, I really don’t care what tools/languages are
    used to make WordPress what it is.

    There is a photograph of four seniors
    looking at a laptop. Why did you use this photo? I what context?

    Kind Regards


    • Thanks for this lengthy reply, much appreciated!

      “There is a photograph of four seniors looking at a laptop. Why did you use this photo? In what context?” -> I used it in the context of an audience that should be extinct. Those unable or unwilling to move on to newer tech. It’s just a stock image, didn’t mean anything specific by it.

      Anyway, to reply to your response.

      The context of this post is web applications. PHP, to be specific, since it was published on the PHP channel – though in retrospect, perhaps I should have made that clearer. Mainframe apps you mention and old software on ancient hardware is, of course, not eligible for simple rewrites. Low level programming is a serious business in which you need to be constantly on your toes about any given hardware or software upgrade, and you’re highly constrained by the environment. In web apps, this is not so. Web apps are simple (and no one will ever convince me that they are not) and easy to build (when using the right technology stack) and will never reach the complexity of low level software. Thus, they are easier to rewrite.

      Furthermore, a common theme of the comments to this post seems to be that I’m of an “upgrade now at any cost” mentality. This is not so. What I’m against is having both a legacy and a modern version alive and in active development at the same time – a scenario that is far too often encountered in the web development world.

      I’m all for new tech, and always use the latest and greatest when starting from scratch, but if you have an app that’s built on an old stack but still fulfills 100% of your and your clients’ expectations, there’s no need for big changes and leaps of faith.

      • Ted van Gaalen

        Astonishing. Am I really reading this ?

        “I used it in the context of an audience that should be extinct.” –>

        Ok, got it.. I am not that old, 63, and it looks like those on the picture are over 70..Perhaps, one day you might reach that age, if so, then how would you like to be classified as a member of a group that you now consider should be extinct ? I hope that I misinterpret your attitude, but to me it seems that you regard older people as stupid, and a nuisance.

        Seriously, I find this very insulting.

        “Those unable or unwilling to move on to newer tech.” –>

        That, in any case has nothing to do with age! What makes you think so? If I would take this personally I would still be programming with punch cards and Cobol only.. I have been in IT probably before you were even born, with years of experience and always state of the art attitude, I could fly in circles around your -PHP only?- world and you wouldn’t even notice it..

        “It’s just a stock image, didn’t mean anything specific by it.” –>

        You’ve selected it, didn’t you?
        You stigmatize older people.So, did the photographer, graying the colors, just one among other “subtile” effects in this picture, that only one’s subconsciousness register..

        If you’d think mainframe programming is low level, just go there and work along with mainframe colleagues for two weeks or so. The difference is, it’s not object oriented, which I’d prefer today, but nevertheless very complex most of the time.

        ? Web apps are simple, you say, although due to its hybrid nature in most cases that is certainly not the case.. “The right technology stack” ? Oh, wow, the holy grail, forget it, because this (components of this) stack change al the time.

        Anyway, I’d suggest you would save this/your writing and take another look at it thirty years from now…

        That’s it from me. I won’t waste my precious time any further -I am sooo old, you know-so much better an enjoyable things to do.

        kind regards

        • Where is this hostility coming from? I didn’t mean to insult anyone by the image, and I can’t believe you’re using it to make any kind of point. I apologize if I offended you. Low level programming, and you should know this if you’ve been in it for so long, means simply programming at a lower level than web – aka you need to be mindful of memory, CPU cycles, and more, as opposed to web where almost anything is forgiven and you have no control over such things.

          I never said all old people refuse to move on to new tech, but I did notice a pattern which clearly indicates that people of age have a harder time accepting new things, much like in any walk of life. This also applies to programming, and I refuse to feel guilty about stating a known statistical fact.

  • Carlos Osuna

    Man. You forget the difference between point (or dot) releases 1.1, 1.2, 1.3, etc. and major revisions 1.0, 2.0, 3.0.

    Major revisions have the intent of breaking compatibility with older versions, in favor of a major rewrite. That’s the reason most OOP languages let you add the @deprecated tag to the code, so coders know that this will be dropped in the next major release.

    But then again, minor releases, must keep compatibility to avoid alienating your user base.

    This has happened time and time again, with software not properly versioned. Best Example is Windows 8.0 vs. 8.1. Some PCs wouldn’t allow 8.1 which left users “stuck” in the older version.

    Open Source software has a different dynamics which is almost always resolved with the “distro” concept. You can’t think of ONLY PHP 5.5, but the full LAMP stack. That way your software at minor releases should stick with a single LAMP stack, by using a convention, say for example, L30_A24_M57_P51 supporting Linux 3.0 kernel, Apache 2.4, MySQL 5.1 and PHP 5.5.

    If you want to upgrade to MySQL 5.7 or MariaDB, you will change the full distro number. Your code should be a major release, as such a change will challenge compatibility.

    • When you say major releases are for breaking BC, how does WordPress fit into that model? They’re about to release version 4.0 with new features an average developer could implement in minutes, and it doesn’t backwards break anything.

      But again, like I said in other replies, I’m not arguing for senseless upgrading whenever you can. I’m arguing against having both a legacy and a modern version alive and in active development.

  • StevenK

    My Moto: “Life is Too Short for Legacy Code!”

  • Davis Hernandez Guido

    Good discussion, I can’t agree with the Article itself, I’m more in the side of update it only if valuable (lets say this is better than “if it aint broken, don’t fix it”)

    You can update because is needed, in WEB development that is more common cause is not fully standardized and there is a lot of updates day by day, the what yesterday was the hot potato, today is the ugly girl no one wants to “update”….

    But in therm of WEB I talk only about Web explorers, what you will build in the BEs, on the servers probably will be using a more stable standard and technology. That means, this code will live for decades unless you chose the wrong technology (the new shiny one that is not trusted enough just because it was the current flavor).

    Of course and what makes it more important: Can your company a fort the change? It’s not just go and add what is new, you need all your team to know about it (training), probably you are already an expert in your current project (you will resolve the problems extremely fast, they will believe your are a magician), and is this new tech giving you real reasons to change? your current tech have issues that will be solved with this new tech? so is there a real value for all the effort? if no, then there is no reason to change, you don’t need to buy Office 365 and the latest PC just to write a Letter and send it by post mail to you uncle, dude a pencil, enveloped and 1 white page will work and will cost 1 dollar.

    oh also want to add, this doesn’t just applies to technology, it also applies to current code, if the code is giving you problems, you need to fix it, probably you will rewrite it in an new paradigm or it can happen in the other way that code looks awesome old, no artifacts!!! no factory!!! but dude that code works perfect, if you try to change it can be chaotic for a while to end having the same result. So just don’t upgrade because you want, be sure to analyze and identify if there is VALUE on the change.

    (sorry for bad english)

  • Indeed.
    I understand that bosses sometimes rush things (which is why I no longer code for other people) just to make a quick buck, but sometimes as little as a couple of days is enough to make a world of difference in the architecture of an application. All modern day code troubles can be avoided if people are patient, and don’t waste time on nonsense.

  • Joel’s post is 14 years old and has little relevant in modern web-related code practices. The web is a very simple environment in which an environment of several dozen layers of architecture is completely unnecessary. Rewriting a web app (especially back end) from scratch is many many orders of magnitude easier than rewriting a native application in a compiled low level language which needs to adhere to various platform limitations.

    Neither the post nor the SO answer apply to the issue of legacy code in web applications.

    • Tarabass

      It’s strange that you, in other replies, am claiming that your post is about serverside stuff and in this reply you are talking about web apps. Your serverside code may never know which type of application is calling his code. For example, it may be a web app but it can also be an mobile app. Or even java software.

      • Bruno Škvorc

        Ok, to clarify, I’m talking about any server side PHP code.

  • Like I said in other replies – I’m not arguing for senseless upgrading whenever the opportunity arises. I’m simply against keeping both a legacy and a modern version alive and in active development at the same time.

  • gggeek

    I agree.
    In fact I am not advocating non-upgrades.
    I advocate the opposite: refactoring-driven-development and backwards-compatibilty-as-much-as-possible

  • True.

  • ARaybould

    For some balance…

    Though, to be fair, this was a technically more demanding project than a web site.

    • It was also 14 years ago, aka last ice age in internet years.

      • ARaybould

        If you have an actual explanation as to why it is irrelevant now, let’s see it.

        • I explained this in another comment. Joel talks about a completely different kind of software that’s much harder to rewrite and plan, especially back then. The web is much simpler than low level programming and, as such, very forgiving about details. This is why it’s much easier to completely rewrite a web app, and almost impossible to completely rewrite an app as complex as a web browser in under a year. Different worlds.

  • Thank you for this article, it really has valuable points.

    About this CMS install “hell”, I think it’s worth mentionning that the little bit that requires the legacy app is the backoffice. I’ll also add that the way the legacy system is included matches most of your good arguments, but given your first impression of the product, it is unlikely that you’ve had a chance to go that far :)

    • Yep, Ivo already mentioned the backoffice in another comment and I’ve since amended the post part. I’ll definitely be looking into the app a bit more eventually, if I manage to win the fight against the installation process.

  • You’re argument is too focused on the business and not the end users.

    Google maps was working great, and then they “upgraded” the UI, and I had to figure out all over how to do stuff I had always done with it. I absolutely fail to see the improvement.

    Google mail decided one day to just stop supporting IE 8. It’s just email. I don’t need anything complicated, just send text, and sometimes attach some pictures or other documents. Email is a wrench. In 5 years, I want that email program to work the same way it does now, just the like the wrench in my toolbox. What possible reason would I have to learn a new UI for email when I’m still just going to be sending text and attachments like I am now?

    Some applications benefit from regular upgrading, some don’t. The key point, though is that whether an application needs an upgrade is really a matter of the end users perspective – some users just don’t need or want your upgrade.

    Think for a moment – if every single last application you use acted like you suggest, would you still be productive, or just spending lost of time needlessly upgrading stuff you don’t need to upgrade right now?

    Users should have a reasonable choice of previous major versions. If you want to cut off any further development, including bug fixes, fine. But I should still be able to continue using the older versions if I want to, until

    *I* feel like upgrading, not when *you* think I should.

    • You’re focusing on front end, I’m talking about back end, though perhaps this wasn’t too apparent from the post.

      • Tony Marston

        But what’s the point of constantly rewriting the back end if no improvements are visible in the front end? If I was a paying customer of your application and I could not see any benefit from your constant rewrites I would be unwilling to pay for them.

        • Bruno Škvorc

          I’m not arguing for constant rewrites – only when they’re needed. Once again, I’m only arguing against keeping both a legacy and a modern version alive at the same time.

          • Tony Marston

            That is not obvious from your opening paragraph.
            As far as I am concerned any developer who changes his application or framework in such a way as to make it completely incompatible with the old version is a poor developer. I released my framework as open source is 2006, and despite many enhancements any application which was built for the 2006 version will still run on the 2014 version. If I can do it then anyone can.

          • Bruno Škvorc

            I’m sorry I didn’t make it clear enough. I’m definitely not trying to say you should upgrade for the sake of upgrading alone.

  • Ivo Lukač

    Topic is an important one. Dealing with legacy code is an important part of any longterm product, service and even a simple web app. Though some valid points are given in this pos, it fails short in general due to some claims that are hard to comment as they are very naive.

    For example you say: “if you follow best practices, respect separation of concerns, encapsulate your services and APIfy your application so you can write front ends completely separate from back ends, there is absolutely nothing stopping you from doing full rewrites in under a month, regardless of the app’s size and/or popularity – provided your team mates are coders, and not theoreticians”
    Really? In a month? With how many developers? If we double the number of developers can it be done in 15 days? So the complexity of the app doesn’t matter?

    Or: “there’s no web application big enough to ever warrant using a big framework like Symfony or Zend.”
    Feels like a spit in the face to people who are developing and contributing to those products. There are many, many reasons why people should use frameworks. I recently wrote an article why I think Symfony is great baseline for more complex projects:

    And you really need to check the facts, you wrote: “including a legacy version of the CMS inside the main CMS, because they share some installation properties.” which is false statement. Sharing some installation properties is not the only reasons why legacy is still there, as explained in the comments of your post about the installation of that CMS. There is a complete back office based on legacy so it can’t be left put until the new content management interface is implemented on top of a new stack.

    If legacy code is a cancer, we could say that rewriting any web app in a month without a framework is a – suicide :)

    • Regarding your first issue, ok, maybe two or three months, tops, but a single developer. Complexity doesn’t matter if the app is modularized enough, as you can easily tackle part by part without affecting others.

      It’s not a spit in the face to either Zend or Symfony devs – like I say in the post, they’re both complex and interesting enterprise products of mostly professional code, but I personally don’t see a need for them (note the category of the post – “opinion”). My opinion can change based on experience and input, and I’m not saying I’ll be of the exact same mindset in 5 or 10 years, but right now, this is what I feel.

      Like I said in all the other replies that assume this, I am not saying you should go framework-free. It is definitely not possible to rewrite a complex app within a month without a framework, no matter how many devs you throw at the problem. I’m saying I don’t see a need for using the big frameworks over the light weight ones, and after having worked for years in a very complex app in Zend, I am convinced of this more than ever.

      I’ll fix the eZ note – it was gross oversimplification on my part to drive a point home, but it was unfair.

      • Ivo Lukač

        You are again trying to estimated something that is unknown. Seems like you have a very limited and narrow thinking of what can a web app feature. So you would be able to rewrite, for example this Disqus web component (that we are using to discuss this topic) with the public features as well as management console and reporting which can also scale to millions of request per day in a few month? Yes, it looks simple on the out side but don’t be fooled. Would you be able to generate a decent amount of documentation that you successors could use for maintaining and extending the code? Check Symfony documentation and the level they achieved.

        Code should be written and developed so its not depended on one man!

        Frameworks offer a baseline (components, best practices, libraries, conventions) which is well documented. You will need less time as a developers to prepare the code for the future. This is valid for a single developer but particularly important for teams.

        Remember, you are tagged here as a SitePoint Staff. You can of course have you opinion but you need to think about other angles too. You can say that you personally don’t need Zend (if you have some personal experience on one project) but discarding all frameworks for all use cases is not fair. This was not clear in the article.

        • Yes, if Disqus is built properly (and on PHP, of course) I would be able to rewrite it – we’re talking back-end here, not front end. When an app is built properly, the front end and back end are fully decoupled, and as I’m not an expert front end dev, I wouldn’t want to get my hands dirty with it – I’d probably just make a mess. But I guarantee I could rewrite the back end in a couple months if the app was built well, along with all the management/admin interfaces.

          I’m not discarding them all. I always use a framework when starting a new project, always, no matter how small. I LOVE frameworks and I wouldn’t go into a serious project without one. Hell, I wouldn’t go into a hobby project without one. I would, however, carefully evaluate which one I need because after having worked in Zend 1 and 2 for years on a very large project, I’m 100% certain the entire project and the team would have fared better if we used any other framework from the get-go, like Phalcon or even Laravel. So, I am thinking about other angles, but I’m also voicing my opinion based on experience.

          Like I said, it’s not impossible that this opinion might change over time as I get more experience, and should this happen I’ll fully acknowledge this.

          • Ivo Lukač

            Estimating something without any even rough spec is like playing lottery. You can be sure by a very high certainty that you will not estimate it well. You will for sure fail the estimates. With a big margin.

            You are a voicing your opinion about big frameworks based on one big project?

            Hm, form all of this I can only deduct that you have problem with probability and statistics.

          • Not about big frameworks, but about approaches to developing with them and their role in today’s web. I don’t hate huge frameworks, I just don’t see a need for them. I’m not sure why everyone seems so insulted, this is my opinion (and I’m not sure why I need to keep repeating this fact), and you’re free to disagree and even prove me wrong. I’d be glad to do the same, given the chance.

          • Ivo Lukač

            I think we can’t continue with this without a beer :)

          • Bruno Škvorc

            Haha, agreed

  • Tarabass

    I couldn’t disagree more. Yes, in the ideal world you might end up thinking like this. But in the real world where steakholders exists and clients (like governments and health care organizations) just can’t upgrade to the latest and greatest you have to deal with a lot of other things.

    For example, writing your stored procedures with the latest functions will end up writing stored procedures that will not be able to run on older sql servers. For example, writing CSS with the latest technologies will end up in not supporting IE7 anymore. I could go on forever on this.

    If you are building big applications you have to be careful and you can’t always go with the latest. It has to proof itself for what is worth. Besides, there are so much ‘new things’ that will not last longer then a year. Especially within web development. I’ve seen so much technologies come and go, even things that felt like future-proof.

    If we were adapting everything new, we followed every single upgrade, we were refactoring 24/7. Refactoring can be a good thing, but rewriting you framework/base all the time is not a good thing. I would dare to say, if you want to move on you need legacy code. You can’t look back all the time..

    • Bruno Škvorc

      I’m only arguing against keeping legacy and modern code alive at the same time, and mostly talking about PHP applications here, not CSS or SQL.

  • phronesis

    There are a few valid points in this article but I think the article is too opinionated! making such absolute claims like no application is big enough to warrant 3 months of code or big enough to use symphony or Zend framework. Sincerely, looks like Bruno wrote such a controversial article to get comments and more traffic… at least as a staff of Sitepoint. I could be wrong… but just thinking..

  • Roy

    I think this article is fundamentally flawed in that you are considering everything from the point of view of the developer, which is wrong. Ultimately, developers create products to be used by consumers, If the world was only made up of developers, then you would be absolutely correct, but that is not the world we live in.

    Do you think WordPress would be so successful if it broke millions of websites and plugins every time it upgraded? Do you think Windows would have dominated back in the day if all the programs people bought broke every time a new version was released? No, it’s precisely BECAUSE these projects have taken so much pain to integrate legacy code that they have been so successful.

    It’s a pain for developers yes, but consumers don’t understand or care about that. They want things that work, and it is the job of developers to do that. If that involves maintaining legacy code in order to achieve a seamless user experience, then so be it. That’s our job.

    • Bruno Škvorc

      “Do you think WordPress would be so successful if it broke millions of websites and plugins every time it upgraded?”

      You’re coming at it from the wrong angle. I think WP would still be this successful if major updates continued on an upgrade path, and old versions were left in maintenance mode only.

      For example, look at WP’s 4.0 release changelog. Does this really warrant a major version bump? I don’t think so. They should make each major version incompatible with the old one (as needed by new architecture), and keep the old one in maintenance mode only.

      • Roy

        I think it would be interesting to see statistics regarding how diligent most real world users are at keeping their WP installations up-to-date. I would imagine normal users are not as eager as developers; I have worked for companies for whom many clients were extremely reluctant to upgrade platforms when they ‘just work’. Ultimately it comes down to who has priority when it comes to supporting legacy code – regular users or developers, and normally regular users usually win out as I think they should.

        • Bruno Škvorc

          Good points

  • Bruno Škvorc

    I appreciate your input, but no, I wrote it to stir up discussion and to express my opinion. This is what I sincerely believe and will continue to do so until proven wrong.

  • Ivan Panfilov

    Legacy Code – is a Gold Mine!

  • Wow, a very controversial and good article. I’ve seen this happen too and actually I agree with you Bruno.

    However, there is a definite and absolute necessity for your position to work. That is, the reasons for upgrading to a new major version which has no or very little BC must give the users or customers much greater pleasure than any of the pains, which not upgrading and/ or upgrading might give them. The user or customer must be in such a “valley of tears” sitting on that old version that not upgrading would be unthinkable or, at the very least, very unpopular.

    Unfortunately, software developers and ISV’s (and I don’t actually mean the devs themselves, but their management) don’t gather their USP guns or have enough marketing prowess, in order to make those kinds of perspectives in their user’s or customer’s minds a reality. And thus, they often go the easier route and try to make everyone happy, by either trying to be compatible to the older version in the new version, most often watering down its success. Or, they keep older versions alive, when they should be long dead. With this method of mild satisfaction, everyone is relatively happy, but the the fewest of them are really completely satisfied. They are all feeling the legacy code shackles and those shackles cause a lot of wasted energy, both on the developer’s and the user’s / customer’s side of the software application fence.

Get the latest in PHP, once a week, for free.