The Case Against Print Statements in your Main Development Branch

A coworker (who is new to our codebase) recently asked me to add print statements, specifically console.log() statements (as we’re using React Native), to our codebase wherever an “important event” happens. He explained that this would help him understand the codebase better.

My knee jerk response was “Absolutely not!” Yet, I never sat down and fleshed out my thoughts on why I am against print statements as permanent fixtures in a codebase. Well, here it is.

What This Blog Post Is

This blog post is my argument against allowing solely informational print statements in a codebase’s main development branch.

What This Blog Post is Not

This blog post is not an argument against using print statements while you code. Print statements are invaluable when writing a feature or debugging existing code. They provide a glance into what exactly is happening as your code runs.

Additionally, this blog post is not about using print statements to log unhandled errors. Error print statement must notify developers of any unhandled errors. This makes them a lot more useful than mere informational print statements.

Lastly, this blog post is not about keeping print statements out of production. It goes a step further and argues that it should never be part of a codebase’s main development branch.

The Negative Effects of Print Statements in Your Development Branch

⛷️ Slippery Slope

Allowing print statements into your development branch is a slippery slope. Are all and any print statements allowed to be merged into the main branch? If not, which ones are allowed and which ones are not? What makes one subjectively useful print statement better than the other? Who decides where to use print statements? If the team decides where print statements are allowed, how much time and resources should be spent on this decision? Where is the documentation and list of good 👼 vs. evil 😈 print statements kept? Who will maintain said documentation?

By now, I imagine you understand my point. A seemingly trivial decision leads to a lot of additional overhead for a development team.

🤯 Anxiety and a Feeling of Being Overwhelmed for New Developers

Seemingly random print statements overwhelm and distract developers who are completely new to a codebase.

As random objects and strings run across the console, anxiety and impostor syndrome may creep in as newer developers, especially those that are junior, may feel they’ll never understand an existing codebase

Additionally, these print statements entice curious developers to find where they stem from and why they are firing (OK, maybe I’m speaking for my distracted self here) even if they have nothing to do with the feature they should be developing or the bug they should be fixing. This, of course, leads to lost development time (though you can argue that this sparked curiosity leads to a deeper understanding of the codebase).

🙉 Noise

Every extra print statement added to the codebase is another print statement that one or more developers will ignore sooner or later. As a print statement ages, its usefulness takes a nosedive. Eventually, even the developer that added the print statement to the codebase will find it useless. What to do with all this noise? A developer now needs to decide which, once “useful,” (see: good 👼 print statements) print statements must stay and which, now “useless,” (see: evil 😈 print statements) must go. Then, they must make a pull request to remove these “useless” print statements. The garbage collection of print statements becomes a recurring task that never ends.

Additionally, “useless” print statements in your codebase leads to…

💔 Broken Windows (and Broken Hearts, maybe)

Imagine a codebase filled with print statements that many perceive as “useless”. They are added carelessly and never cleaned up before going into the development branch (because, hey, print statements are allowed in our codebase now). These evil print statements become technical debt that must be cleaned up (as they are now noise). In an ideal development world, this technical debt is cleaned immediately because this seemingly small problem can lead to big problems: one part of the codebase that goes unfixed leads to another part of the codebase that is left unfixed leading to another. Eventually, a small problem snowballs into many small problems that snowball into one ugly codebase that is a drag to work with.

This is the broken window theory. Don’t let print statements break your heart and lead to a codebase full of broken windows.

🐛 A Codebase that is Harder to Debug

We’ve established that the console is a mess due to all those 😈 evil print statements that are yet to run through the human garbage collection process. Every click of a button leads to dozens of useless print statements.

Now, you need to develop a new feature and want to add those useful print statements (that every developer uses) to ensure that a function runs properly, an HTTP request is properly made and the server response complies with the data contract. You add your print statement which is now caught in the noise of a bunch of useless print statements.

The codebase is harder and more time-consuming to debug as new print statements must be located in a sea of other print statements. Anything that makes a codebase more difficult to debug is a huge negative (as this leads to more bugs in the code).

❌ Mistaken Logs in Production

With dozens of print statements in your codebase and many being called multiple times, your surface area for a big mistake increases. More specifically, the chances of logging a real user’s personally identifiable information (PII) increases.

That said, if print statements are allowed in your codebase, you must strip them before going into production. Of course, this is one more piece of maintenance that must be done to support your dear print statements. 😴

Conclusion

A decision as innocuous as allowing print statements in your main branch may have huge effects on your code. Of course, every codebase and development team is different. Take the time out to analyze this decision (and all decisions!) with your team.

Code safely.