Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

If I had superpowers that allowed me to delete one website from the in internet forever, it would be this article.

I find the "complete code rewrite" to be the most powerful programming technique I have in my repertoire.

In 2007 I wrote an application called FlightLogg.in. It was basically a clone of logshare.com that I wrote in my spare time with PHP. It was my first really 'big' project. You can see the code here: https://github.com/priestc/old-flightloggin

If you look around that codebase, you'll see nothing but spaghetti. I starting writing the app in late 2007, back when you could say I was a 'noob' (so noobish in fact, I didn't even use source control). At the time I thought I was writing the most awesome code ever. By the middle of 2008, that project had reached a state where it was pretty much 'done'. I then stopped working on that codebase, and moved on to other projects.

Then by late 2008, FlightLogg.in's traffic had kept growing, and there was a list of bugs and really cool features that I had thought up since I last touched the codebase a few months earlier. I set out to continue development on the PHP codebase. The problem was that in the past few months I've been away, I had become a better programmer, and the sight of that spaghetti code made me vomit.

It was less about the code being 'bad', and more about me not remembering how things worked. The small set of fetures and fixes I wanted to make would have taken me a few hours to do back when I was first working on this codebase. Since a few months time had passed, it was taking me much longer.

Eventually I decided to do a complete code rewrite. This was before I ever saw that Joel Spolsky article. The new codebase is here: https://github.com/priestc/flightloggin2 It took me roughtly the same amount of time to build the new codebase as it did the old codebase.

Ever since, each and every project I take on, I accept the reality of doing a complete code rewrite might come up. For my own personal projects, I do complete code rewrites all the time. On the other hand, at the various jobs I've had over the years, its a much different story. If I came into work today and brought up the idea of doing a complete code rewrite, I'd either get laughed out of the room, or even worse, threatened with being fired, thanks to this Joel Spolsky article. Thanks Joel.



Joel isn't talking about the kind of software that can be rewritten in a few days or weeks. He's talking about "large scale commercial applications" ...

If you have an app with a complex codebase that is making money in a pretty competitive space and you decide to stop everything and do a complete refactor (the blocking kind in which you can't do anything else while that is going on) then you find yourself in a situation where you can easily be surpassed by a competitor. Its probably a smarter move to do a more 'gradual' refactor.


Assuming your code base is even clean enough to do that. Lack of encapsulation and modularity is also part of technical debt. Getting a disastrous codebase to the point where gradual refactorization is even possible will be a blocking task, and if the technical debt has built up high enough, just that single blocking task may cost you more than a complete rewrite. It depends on the code base and how much foresight was had when it was first written. If technical debt is such a serious problem that you're even considering a total rewrite, the blocking debt may be so massive that it makes a gradual refactor impossible.


Did you really mean to use the phrase "complete refactor" here? AFAIK, refactoring means modifying your code without modifying features. That's very different from a "complete rewrite".


Its not like I had to shut off the old site while I worked on the new codebase... The old codebase was running perfectly fine, up until I shut it off and replaced it with the new code.


There are plenty of projects where by the time you've finished your rewrite the product will have moved on so far that you'll have to rewrite some again. I seem to recall Facebook making several attempts to rewrite in a language other than php but the codebase just evolved too quickly.


You don't rewrite for features. You rewrite for better maintainability and productivity. After your rewrite you shouldn't have to rewrite it again. The balancing act is that a rewrite should improve your implementation velocity, so while it may be a setback, your velocity should be much higher than your competitors, so over time you would be able to surpass them and then gain a lead they cannot beat thanks to your higher productivity. As the technical debt grows, your productivity will get slower and slower, so you won't be able to keep up with your competitors anyways. That's the gamble.

Just because Facebook was written in PHP doesn't mean that the code was unmaintainable. I don't know if it was or not. The problem they had was that it was unscalable, and they didn't do nothing about it. They wrote a PHP to c compiler, and that's a monumental task. So they paid their technical debt in a different way that they decided was the most efficient way for them to deal with it. If the problem isn't scalability, and is maintainability, you may not have that luxury. Unmaintainable code's problem is inherently in its structure, and the only solution for that is refactorization or a rewrite. The code may be so unmaintainable that even refactorization isn't really possible. The best offense is a good defense. Deal with technical debt from the get go. Sure, write your MVP in a weekend just to test it, but rewrite it early for maintainability while it's still small and possible.


Fair points. I guess I was reacting more to the fact that the original example probably wasn't of the scale (single person) to use as an example. The Facebook case is definitely different in that they were building new features too fast to keep up with.

My project (single developer) is undergoing a big underlying change (switching from MongoDB to Postgresql) at the moment. I still need to keep development going on the live branch while I do this work. I'm doing it because I'm having maintainability issues with the data store that I've been putting off for a couple of months. It's as you say - make sure you refactor before you discover that refactoring is impossible. It's something I do regularly and my business partner has noticed that after a refactor of a component he gets other features faster so that's the only justification he needs.


But are you adding new features to the old codebase? The challenge is when the rewrite takes longer than planned (e.g. Netscape) and your old product is no longer competitive but the replacement (which, as a rewrite, may not include any new features) is not ready.


It appears that for your case, a pretty new and small project, doing a complete code rewrite was the right choice.

However, for BIG codebases (especially those that you didn't write yourself !!!! ), I'd say Joel is spot on.

The company I work for is currently busy throwing five million dollars down the drain on a greenfield re-development of a bad but servicieable insurance package, when they could have either overhauled it or bought a commercial product - which they deemed "too expensive, but I'll eat my backpack if the final rewrite isn't both late and over the budget of the commercial product. It's not a Netscape-style failure, but it will probably cost it a lot of market share.


Even for smaller projects it may not be the right choice.

I had a side project I work one that would take a complete re-write to make it testable as well as being able to work better in Windows 8.

But I find that when I think about it, it's a huge amount of work and while new features and bugs can be annoying to fix (lack of tests also means inevitable regressions), but still far less time consuming than a re-write.

Plus, if I completely rewrite it so it's awesome and more flexible, I expect that my revenue will probably be about the same as it is now. Rewriting it won't increase my sales unless I'm able to add features that would be impossible in the current code.


It's not just(!) the five million dollars that they are throwing down the drain, think of the opportunity cost spent in what you didn't develop during all that time you were basically running to stand still.


Yeah, I'll be abandoning the Titanic ASAP :) .

It's an insurance company, it shouldn't think of itself as a software shop. It does sometimes make sense to build stuff in-house, but not an insurance package (reinventing a pretty expensive wheel).


Well, if they look at their ability to make an effective insurance package as a competitive advantage instead of a necessary evil, I don't see anything absolutely wrong with an insurance company making insurance software, but I'll defer to your domain expertise :)

Good luck.


It's a small subsidiary of a big insurance company, with 120 employees in the local branch (20 of which are now in software) and 45 million dollars in premiums (that's sales, not profits).

They hired a new CTO, who hired a new team specifically to write the new software, and are NOT using any of the old developers' knowledge (me and 2 others are stuck maintaining the old software).

The new team blew the deadline for the first small module (a small subpart of claims management) by 6 months (the old team had estimated 2 weeks for delivery of that module if we had done it ourselves).

They vastly underestimate the effort and have no idea of what they got themselves into (and they're paid employees, it's not like they can be sued for not delivering).

It doesn't make sense for a company that small to divert that much effort into a non-core competency.

Now, if the parent company (10.000 million in premiums) decided to build their own insurance software, I believe they could do it right :) .


Personal projects are one thing. But company projects involving more than 3 programmers? Forget it! He's right about these projects - you shouldn't rewrite them. First of all the experienced people will probably move on, secondly business pressures will never allow you to do things "just right". I can't tell you how many rewrites I've seen fail, compared to the handful of rewrites that actually achieve their goals. And this is a very risky proposition for a company.


If I came into work today and brought up the idea of doing a complete code rewrite, I'd either get laughed out of the room, or even worse, threatened with being fired

If that's really the case, then you're working with a bunch of abusive, pedantic, and narrow-sighted assholes. I will generally say "no" to the idea of a complete code rewrite of any meaningful and currently useful system (based on my own experience as much as Joel's article), but I won't laugh at people or threaten to fire them over it.


Or they may have experience with people that walk in and declare all code as "insecure" and "dangerous" or "unusable". They usually promise the world and deliver a small fraction, if even that.

Then, for the next 9 months delay the "1 month" project week after week. The product owners love this one. It cost them hundreds of thousands of dollars to get to square one again.

And all of this happening to a product that wasn't released yet.

At the end, the developer quit and everyone in the company agreed that it was good to see them leave.


Good to see you're not bitter about that.


Well, I am young, so I may go through something like this again. But at the moment, I was totally against it.

Now, when something like this comes up again, I learned enough to PLAN through it better. Realistic deadlines will make any work place a better place to be.


Of course, and it is easier to plan for incremental replacement and refactoring than for a wholesale re-write.


Technical debt will never go away unless you confront it directly. If you put it off for too long you simply cannot recover it. Yes a complete rewrite is painful, and can kill you, but so will technical debt. By the time you're drowning in it, there really isn't any easy escape, if there is one. The cost to fix is an investment, it pays off over time, so any refactorization work will eventually pay off, it's just a matter of whether you can pay the cost. Eventually the cost will be so big that a full rewrite will be cheaper. If Netscape didn't do a rewrite, their technical debt would have stayed and they would have died a slow painful death. The real worst mistake you can make is having a policy of putting off technical debt. I've seen it kill companies, and for them, it's a permanent death with no hope of a revival.


Joel's article is cautioning against the kind of cost/benefit-blind thinking that makes "rewrite all the code" a default option. Actually, I think in a certain way your story - perhaps unintentionally - agrees with this point.

In your case, you accepted the cost of doing the project over, which as you said was to write it again taking the same amount of time. The fallacy that Joel is talking about is engineers thinking that they can do a total rewrite of some software that took years to build in some much shorter period of time with better code. The predictable result is huge financial losses, and sometimes even a total market abdication.


"It took me roughtly the same amount of time to build the new codebase as it did the old codebase."

Imagine if you spent that time re-engaging with, documenting, and cleaning up the old codebase - you could have also added a bunch of new features in the time it took you to get up to feature parity with the new rewrite, which also doesn't have documentation and doesn't have any additional features. If you're like me, you'll find out when you go back to look at it in 7 months that you again don't understand it. What then?

It's better just to accept that there is cognitive overhead involved with going back in time in your projects. But it's worth it since the cost of a re-write is higher.

There are very few circumstances where re-write costs less - and I think it's when the exact financial cost of the technical debt from the first version outweighs the overhead of the re-write. Sometimes this happens, but it's not very often.

I'll admit that I've done exactly one rewrite and it was exactly in this type of situation. I was rushed on a project with a new employer and forced to use a language I despise, PHP. The project was to create a document management system for power plant engineers. I had to come up with a production ready system in a month and a half. I did, but of course, it was initially very buggy, poorly designed, with no unit tests, and written in a sub-par language(Sorry PHP fans.)

In this very rare case, the (in my mind unavoidable, thanks to the time constraint) technical debt from the first version was so high that a complete re-write made sense.

I have since rewritten the entire project in Scala with the initial project in production (and most of the initial bugs fixed). I did so understanding that from a financial perspective, there was a certain amount of overhead in re-writing it. But I felt that the technical debt outweighed that overhead. In this case, I did so much integration testing and unit testing on the re-write that I was able to get it up to feature parity without many bugs in about the same amount of time.

But I know that because this code is properly documented, architected, and unit and integration tested, I will never, ever re-write this version, because it will never make sense to do so.

Which is the lesson: Take the time to design your system right, and test every component, the first time and there won't ever be a need for a re-write, because you'll always be able to look at the code and tell what it does.

"I'd either get laughed out of the room, or even worse, threatened with being fired, thanks to this Joel Spolsky article."

I doubt very many people remember this blog post from 14 years ago.


The last project I worked on we were doing rewrites by replacing specific functionality and displaying that within an iframe. Over time we slowly replaced various pieces and added new functionality in a new code base with the end goal to eventually replace it all.

In the end, the last project we took upon ourselves turned out to basically require a rewrite of the majority of the app and the rewrite was scraped at about 80% completed.


> the rewrite was scraped at about 80% completed.

Which rewrites were scrapped? All of the iframe rewrites or just the last feature rewrite? Was the result considered a (partial) success or a failure?


Just the last feature, the previous ones were completed and deployed. The department shifted focus which left us with a small window to finish up the project and we weren't able to get all the features done in that time frame. Had the department shift not happened, we could have finished within about 2-3 months.

I actually think we should have deployed without re-implement every existing feature, but enough to make it work for most use cases (with an option for users to switch between old and new), but there was concern that we'd drive up support costs during our pivot and they wanted to avoid the distraction.

So the project wasn't a failure, but a department-wide pivot put restrictions on the project and made it less attractive to finish.


I think an essential part of Joel's point is that the existing code was written by other people, and you get the impulse to rewrite it rather than read it. If you wrote the first version entirely by yourself, then you probably have a good idea of what's in there and what it would entail to rewrite it.


Complete code rewrite is only good when you are in a learning stage or when the project is not too big. Incremental update is much better and allows new features to be added without halting all the project for rewrite.


You have to remember that at the time it was written, complete code re-writes were a lot more common and often had disastrous results.

Sure, I've also completely re-written systems in a way that wasn't disastrous. I'm doing one right now. But the legitimate case for it is sufficiently rare to deserve some extra scrutiny, even if it is a more fun approach for the developers involved.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: