Code Accretion

- 4 min

Code isn't written, it accumulates chaotically


If you've ever worked on a software project for an extended period of time, you know one undeniable truth: a codebase isn't written, it's accreted.

Codebases, especially the old and sprawling ones, don't grow like neatly. They coalesce through a patchwork of bits and pieces here and there. Patches, bug fixes, feature additions, deprecations, todo comments, and unfulfilled promises of "cleaning it up later".

The longer a project runs, the larger it gets, and the more hands that have touched it, the more its history becomes evident in every corner.

Code Accretion
NASA releases newest image of your codebase

What is Code Accretion?

Code accretion is the slow, steady accumulation of code over time. Each new feature, bug fix, refactor, or quick hack adds another layer to the codebase.

Unlike the clean, greenfield ideal we all dream of, real-world codebases resemble geological strata: remnants of past decisions, tools, and architectures compacted together.

Accretion happens for a few reasons. Business needs change and evolve, forcing requirements to shift, priorities to change, and new features to take precedence over refactoring, testing, and cleaning things up.

As teams grow and change, engineers bring with them diverse philosophies, habits, and shortcuts, which leave their mark on the codebase.

Looming deadlines often lead to corners being cut in the name of speed, accompanied by promises to "clean this up later." We all know there is often no "later".

Meanwhile, the tech itself marches on, as frameworks, libraries, and tools fall out of favor, leaving behind fragments of what was once considered modern.

The Symptoms

Newer parts of the codebase might follow conventions different from older parts of the codebase, creating inconsistent styles.

Commentary relics often linger, with comments like // TODO: Rewrite this or // Quick fix for now far past their expiration dates.

Obsolete functions, unused but never-deleted utilities, remain because "it might be used somewhere," creating a risk no one wants to take.

Layers of abstraction pile on as each new feature introduces its own wrappers and helpers, often built on top of pre-existing layers.

Finally, mystery decisions abound—code that no one on the current team fully understands, rooted in problems no longer relevant.

How To Manage It

While it's impossible to eliminate accretion entirely, it can be managed. The two most important actions you can take are documenting, and cleaning.

Documentation

Documentation is arguably the cornerstone of maintaining a healthy codebase, yet it's frequently overlooked, mishandled, or executed poorly.

Documenting individual components of the code, such as methods or functions, is essential. But it doesn't address the bigger picture.

What truly needs documentation is the system as a whole. Individual components will inevitably change over time, but the overarching structure and logic of the system provide the critical context needed to effectively work on the codebase.

Proper system-level documentation ensures that newcomers can hit the ground running, equipped with a clear understanding of how the codebase operates as an integrated whole.

Spring Cleaning

Codebases should undergo regular cleaning to maintain their health and efficiency. When starting new work, it's helpful to approach it with the mindset that "parts of this might be removed in the future."

If it's your job to write new code, it's also your job to manicure old code, or else you'll inevitably be staring at an amalgamation of unreadable nonsense in the not-so-distant future.

The "Kill It With Fire" Approach

Sometimes, it's ok to rip out a while chunk of code. Most people wouldn't recommend broad re-writes

Be ready to remove outdated code, and write in a modular way to prevent new code from becoming entangled with older, less stable layers.

Scheduling regular refactoring sessions provides teams with opportunities to address high-impact areas before they become deeply entrenched in technical debt.

Starting with the removal of dead code and unused features lays a solid foundation, but simplifying overly complex and intertwined code is crucial for maintaining long-term manageability and clarity.

And of course, adopting coding standards and instituting test coverage requirements helps align the coding style, and prevents regressions during refactoring.

Conclusion

A codebase isn't a static, it evolves over time. Code accretion reflects the history, growth, and compromises of your project. Instead of fighting it, learn to work with it, managing the inevitable layers with care and intention.