TODO, or not TODO

3 minute read

TODO, or not TODO

That is the question

Should you add TODOs in your code? This topic sparks a debate in the programming community, and the consensus is as clear as the “tabs versus spaces” one…

I’ll try to synthesize the divergence of opinions and the main arguments of each clan (oh yes, this is serious stuff!) with a focus on helping you make the best-informed decision for your project.

What others say

After reading a dozen blog posts explaining why TODOs should be avoided, three arguments often came back.

  • Lack of visibility. Having TODOs spread across a codebase is hard to keep track of, both for its original author and even more for others. The causality being that TODOs are quickly forgotten.
  • Many programmers believe TODOs are synonymous with bad code and shipping incomplete features. It was frequent to see TODOs assimilated with inglorious wording such as “developer shame list” or “apologies”.
  • The lack of conventions around TODOs, making them cryptic and vague.

From the multiple conclusions I gathered, the solution preferred over writing developer notes was to use a ticketing system (Jira, GitHub issue).

# TODO Fix this later

A bad TODO. Cryptic, vague and no one is accountable for it.

By contrast, let’s break down the three main arguments for why programmers write TODOs:

  • An interesting contradiction was the fact that TODOs help with visibility in some circumstances. For instance, being able to pinpoint a workaround that doesn’t require much context to address.
  • TODOs help organize the train of thought without losing sight of the end goal.
  • Great way to work in iteration.
# TODO(@edouard): Remove this gem when Ruby 3.2.0 is released.
#   The Regexp timeout feature was added to the language.
gem "safe_regexp"

A better TODO. Clear owner, concise explanation, and a well-defined timeframe to address it.

Questions to ask yourself

Ultimately, the decision to allow TODOs remains yours to make. This post has no vocation to provide a canned response. And like many things in life, it depends. However, to help guide your decisions, there are a few points to consider.

First of all, it’s worth highlighting that it’s pretty clear that programmers are not debating about the usefulness of TODOs but how to surface them.

If you plan to ban TODOs in your system, provide an alternative and ensure there is a clear call to action. For instance, a linter that flags TODOs and fails your CI with a generic “TODOs are not allowed” message comes with the risk of having its author delete it with no replacement solely to make CI pass.

An issue tracker doesn’t solve all problems. You should take into consideration how healthy and updated it is. An unmaintained or untriaged issue tracker discourages team members from regularly checking it. Your technical debt will end up buried quite quickly. A TODO gets the advantage of being right in your face when you open a file.

Instead, if you decide to allow TODOs:

  • Make sure authors are accountable for their TODOs.
  • Figure out the best way to surface them for everyone in your organization.
  • Determine a plan to ensure TODOs get addressed on time.
  • Provide guidelines. A complex issue requiring diagrams or screenshots to help understand the problem should likely not be a TODO.

You can address all these points with strong conventions, self-discipline, and good tooling.

Conclusion

TODOs are not perfect, but neither is a ticket on a tracker, each having pros and cons. I believe TODOs can be extremely useful and help developer productivity when used correctly and with the right tools—which are getting increasingly better over the years. Frameworks, IDEs, products, and even modern programming languages now provide built-in support.

The TODO controversy is probably as old as the “spaces versus tabs” one, and I don’t expect it to end anytime soon. Everyone has their preferences and uses what works best for them, and so should you.

Finally, I’m of the opinion that TODOs are not going anywhere because of how convenient they are (a quick search on GitHub comforts me with this idea). The solution shouldn’t have to be as radical as banning TODOs, but more and better support around them would help appease this debate, which I hope to achieve with Catana.

Catana dashboard
A TODO on the Catana dashboard

Updated: