Don't Live With Broken Windows

How to keep your codebase in good shape by fixing small issues as they come up.

Issue 22 /

Hey friends đź‘‹ I hope your week went well. Mine was pretty good, but exhausting. We moved to a new house a few days ago, so my life this past week has been mostly packing boxes, moving boxes, unpacking boxes, and looking for things in the wrong drawers.

Luckily, this upcoming week I’m going on a long-awaited and much-needed vacation with Patricia and the kids, so my life for the next few days will be packing luggage, moving luggage, and unpacking luggage… but at the beach!

Anyway, I didn’t want to go on my next exciting packing adventure without sending you this week’s issue first. Today we have a short but sweet essay about one of my favorite programming tips, a pretty great talk by Steve Sanderson, and a Github repo with more resources than you can consume in an entire year.

Let’s dive in!

SOFTWARE DESIGN

Don't Live With Broken Windows

Photo by Carl Kho on Unsplash​

In the early 1980s, a group of social scientists developed a theory about why some buildings in lower-income neighborhoods are clean and beautiful, while others seem damaged beyond repair.

In their research, they found a particular trigger mechanism that can very quickly turn a pristine building into a forsaken dump—a broken window.

A broken window, left unrepaired for a period of time, sends a signal to the people who live in the building that nobody cares enough about it to fix it. So after a while, more windows get broken. People start littering. Graffiti shows up. More serious damage is done. And soon enough, the building becomes so damaged that it’s now truly beyond anyone’s desire to fix it.

We’re talking about the decline of a building here, but we could have just as easily been talking about a software codebase.

We should note that the implications of the broken window theory in the real world have become controversial in recent decades—particularly in the way the theory influenced police enforcement. But when it comes to programming, it continues to be a powerful and accurate analogy for how tech debt tends to spread uncontrollably over time.

Dave Thomas and Andrew Hunt introduced software developers to the broken window theory in their classic book, The Pragmatic Programmer. In their book, they also tell us why a single broken window can make such a massive difference:

Psychologists have done studies that show hopelessness can be contagious. Think of the flu virus in close quarters. Ignoring a clearly broken situation reinforces the ideas that perhaps nothing can be fixed, that no one cares, all is doomed; all negative thoughts which can spread among team members, creating a vicious spiral.

“No one cares and all is doomed” is precisely the feeling we get when we see a React component that takes 12 props and we decide to add a 13th to it without giving it too much thought—which is why broken windows are so dangerous.

The real damage of a broken window is not that it makes the code messier and hard to look at, but that it makes it much easier—and convenient—to keep breaking windows in the future.

Take the messiest file in your codebase, for example. Like that 1,000-lines-of-code custom hook that nobody wants to touch for fear of bringing the entire application down. Look at the file history in GitHub, and track it down to its first version. What do you see?

Chances are you’ll see a pretty simple function, properly named, and with one clear responsibility. So how on earth did it turn into the monster it is now? The answer is in all the intermediate commits in the file’s history: one broken window at a time.

Global variables are another good example. Your codebase might go years without a single one, but as soon as someone creates a globals.js file to make something accessible via the window object, it’s only a matter of time before your entire architecture depends on them.

By themselves, broken windows might seem harmless. “It’s just one tiny little any”, I hear you say, “how much damage can it do?”

But make no mistake, broken windows are contagious—and they’re on a mission to spread out.

Fixing them up

The broken window theory gives us another important insight—the sooner we fix a broken window, the more we reduce the chances of a building (or codebase) turning into an unmaintainable mess.

So it’s no surprise that the advice that we get from Dave and Andrew in The Pragmatic Programmer is to fix them up as soon as we can.

Don’t leave “broken windows” (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is discovered. If there is insufficient time to fix it properly, then board it up. Perhaps you can comment out the offending code, or display a “Not Implemented” message, or substitute dummy data instead. Take some action to prevent further damage and to show that you’re on top of the situation.
​
We’ve seen clean, functional systems deteriorate pretty quickly once windows start breaking. There are other factors that can contribute to software rot, and we’ll touch on some of them elsewhere, but neglect accelerates the rot faster than any other factor.

That last sentence is worth calling out. Out of all the things that can cause a piece of software to accumulate tech debt (inexperience, poor decisions, lack of time, and so on), showing that you don’t care about the quality of the codebase is the most damaging one.

“Don’t live with broken windows” is one of my favorite pragmatisms and, dare I say, a principle of good software design. But I realize it can sometimes sound like empty advice—almost like saying “don’t write bad code.”

So just so you won’t accuse me of giving you advice that means absolutely nothing, I’ll leave you with a couple of practical ways in which you can apply this theory to your own codebases right away:

  • Look for broken windows in code reviews. These little infractions are much easier to spot in somebody else’s code than in our own. After all, our own code is always perfect and our windows are always intact, and anyone who says otherwise is clearly wrong. So take advantage of code reviews to look for opportunities to fix broken windows before they have a chance to propagate through the codebase.
  • Leave the codebase cleaner than you found it. Maintaining a codebase is a team effort. So if you’re changing a file and you notice it already had a broken window in it, take a few minutes to see if you could easily fix it up. This doesn’t have to be a big deal, either. A lot of broken windows can be fixed by just giving a function a better name, or grouping booleans into meaningful variables.

Finally, if you’re looking for more examples of tiny 1% improvements that can make a big difference over time, I can highly recommend Kent Beck’s latest book Tidy First? Among other things, the book has a collection of mini-refactors that can help you identify and fix broken windows before they take over your codebase.

ARCHITECTURE SNACKS

Links Worth Checking Out

Understand the Next Phase of Web Development by Steve Sanderson

đź“• READ

  1. Never run out of things to read with this massive list of books, articles, courses, and tons of other resources that will take your programming skills to the next level.
  2. The one and only Bramus just released a 10-part video course to learn all about scroll-driven animations using CSS or JavaScript.
  3. Say hello to Effect, the missing standard library for TypeScript that finally answers the question, “What if Lodash had been invented by functional programmers?”
  4. Chris Coyier wrote a fun article about building HTML Tooltips using a new platform API that recently became available in all major browsers—the Popover API.
  5. If you’re considering writing a design doc for your next project, you should check out this classic article by Malte Ubl on writing design docs at Google.

​

🎥 WATCH

​Understand the Next Phase of Web Development by Steve Sanderson

This talk at NDC London 2024 is a fantastic way to catch up with everything that’s been going on in the world of web development in recent years. From the features that most modern frameworks are converging on (like streaming SSR, enhanced navigation, and interactive islands), to the state of WebAssembly in the server, with seamless interop across languages thanks to WASI Preview 2. It’s a super fun talk and it’s full of cool demos—highly recommended!

​

🎧 LISTEN

​SSR web components for all with Brian LeRoux

The team that builds the Enhance framework is working on a pretty cool technology called Enhance WASM, which aims to bring server-side rendered web components to every server and language. In this chat on the JS Party podcast, Brian LeRoux from the Enhance team shares in detail how this new library works under the hood, and how older codebases in particular could benefit from it.

That’s all for today, friends! Thank you for making it all the way to the end. If you enjoyed the newsletter, it would mean the world to me if you’d share it with your friends and coworkers. (And if you didn't enjoy it, why not share it with an enemy?)

Did someone forward this to you? First of all, tell them how awesome they are, and then consider subscribing to the newsletter to get the next issue right in your inbox.

I read and reply to all of your comments. Feel free to reach out on Twitter or reply to this email directly with any feedback or questions.

Have a great week đź‘‹

– Maxi

Is frontend architecture your cup of tea? 🍵

Level up your skills with Frontend at Scale—your friendly software design and architecture newsletter. Subscribe to get the next issue right in your inbox.

    “Maxi's newsletter is a treasure trove of wisdom for software engineers with a growth mindset. Packed with valuable insights on software design and curated resources that keep you at the forefront of the industry, it's simply a must-read. Elevate your game, one issue at a time.”

    Addy Osmani
    Addy Osmani
    Engineering Lead, Google Chrome