No matter how great a developer you are, nothing is more embarrassing than yesterday’s code. In the rush to launch a business, you’ll likely cut corners and make difficult decisions. You’re going to feel like the old code is holding you back. You’ll want to fix it. You might even be tempted to start over.

We’ve all faced it: do we rebuild from scratch or just refactor? With personal sites, rebuilding seems to be the default option–it’s exciting and new. We see a mess of code and an atrocious design, so we rebuild it. But that’s not necessarily a good idea when you have a web application that thousands of people rely on. This is a decision where you don’t want to let your emotions get the better of you.

If your application is successful and profitable, refactoring is far less risky than rewriting. But if your application hasn’t seen any significant adoption or is otherwise stagnating, a rewrite might be just what you need to breathe new life into it.

Rebuilding

The big advantage of rebuilding is that it gives you a fresh start. You know more now, and you’ve learned from your mistakes. A rewrite may seem glamorous, but that’s not really a business reason. The inclination to rewrite is often founded in an emotional belief that somehow “It’ll be better this time.” If your business is languishing–or never really took off–or if your technology stack is becoming long in the tooth and it’s affecting hiring, rewriting might be the way to reinvigorate your business. It’s also a gamble, so it’s not a decision that should be taken lightly.

That’s where the benefits of rebuilding end. Rebuilding an application from scratch carries a mountain of risks and problems that could hurt your business even more than doing nothing. Before rebuilding, think long and hard about whether your decision is internally or externally motivated. Rewrites are often driven by internal pressures–it’s not as if your customers can see the clutter behind the scenes. Ask yourself how a rewrite would benefit existing customers. If you can’t name any direct benefits to your customers, a rewrite is probably not the right move.

Migrating to a new technology stack is one of the few legitimate drivers for rebuilding–if doing so were to offer more agility, widen your team’s potential talent pool, or allow you to do things that were previously impossible. Don’t rebuild just so you can change stacks, but if your current stack is holding back your business, rebuilding may be the way to go.

Rebuilding inherently leads to stagnation due to its long release cycle. With a complete rebuild, it’s easy for your application to appear to have stagnated even while you’re working vigorously on the new code. So now, not only do you have to catch up to your previous feature set, but you need to release something that’s a significant improvement. Otherwise, you’ll have invested a lot of time in what customers may perceive as merely an equivalent product.

If you’ve only ever redesigned a personal website, you probably aren’t aware of just how important comfort and familiarity are to your customers. Even some of your smallest changes can lead to frustration and support requests. A complete overhaul can alienate a significant portion of your customers who like the new version less than the old one.

As well as bringing a higher risk of major bugs, rebuilding creates many small bugs–the more code you change, the more bugs you’ll have to deal with. Launches aren’t easy, and when you already have a sizable user base, it’s nearly impossible to catch all the edge cases before you go live. Trying to help customers acclimate to the new system while tackling any new bugs that have cropped up makes for a tough launch.

No matter what you tell yourself when you decide to rebuild, you’re going to be tempted to increase scope. Starting from scratch makes it easy to get waylaid by new technologies and features. This can cause further delays and more bugs, and generally make the project that much more difficult to complete. A rewrite requires massive amounts of discipline to stay on track and make meaningful improvements.

Unless you can point out clear-cut business benefits, I don’t think rewrites are your best option. If you’re not planning to change your technology stack, I think you’ll be much better off making gradual and consistent improvements.

Refactoring

The biggest downside to refactoring is that it’s not as dramatic or exciting–you aren’t starting with a clean slate. Refactoring is more efficient in many ways, but can take a while to have far-reaching results. There’ll be frequent small wins, but without big updates you have to trust that things will improve meaningfully over time.

The nice part about having constant small wins is that you’re more agile, and the cycles are faster. Releasing updates often can help keep morale high, and it ensures your customers see regular improvements.

Shorter and faster release cycles also help you balance refactoring with features. You might spend a couple of weeks refactoring behind the scenes, before switching to customer features for a spell. This helps alleviate any perceptions of a stagnant product.

One of refactoring’s biggest benefits is that it’s low risk. Updating a few small portions of your application at a time ensures that any new bugs will not only be isolated to specific areas, but also appear in lower and more controlled quantities. And when your work is broken down into smaller pieces, it’s also more predictable and repeatable. This can help you maintain momentum.

Refactoring also provides a more structured learning environment. I know I’ve learned far more by seeing what I did wrong and forcing myself to fix it than I would have if I had just thrown it away and started from scratch. Bad habits have a way of recurring unless you can break them. When you’re refactoring code, you’re compelling yourself to improve it rather than allowing yourself to make the same mistakes again.

One potential drawback of refactoring is that it can be tempting to refactor everything in sight. There are pieces of Sifter I would have loved to completely rebuild. (In some cases, we did.) Occasionally I’d come across some code and just wince–I’d get the itch to update it simply because it was ugly. That code may have worked, and it may have been well tested, but I didn’t like it. Refactoring can be a dangerous distraction, and I regularly found myself fighting the temptation. Sometimes I’d give in, but for the most part I’d hold off refactoring unless I knew customers would see benefits in the long term.

Deciding

In the debate between rebuilding and refactoring, it’s best to avoid either. Invest in your code quality up front–it will pay off in spades. We invested heavily in tools that helped us stay on track, and we came to rely on two in particular: Skylight, which helped us identify areas for application performance or reliability improvements; and Code Climate, which helped us identify and prioritize code we should clean up.

I’d strongly suggest using those–or similar tools–to act as an angel on your shoulder. They’ll help you identify the most important places to start, and they’ll keep you focused on the right things. And although I think it’s worth trying to avoid refactoring and rebuilding alike, I’d generally recommend that you first consider refactoring and leave rebuilding as a distant second choice.