We’ve all been there. You’re deep in a flow, you find a small optimization or a edge case you can’t handle right now, and you type the magic words:
// TODO: Fix this later.
You feel good. You’ve acknowledged the debt. You move on.
Fast forward three years: that comment is still there. The person who wrote it has left the company, the context is gone, and that "TODO" has officially become a ghost in your codebase.
TODOs are where good intentions go to die. But they don't have to be.
The Problem: The "Set and Forget" Trap
The reason TODOs fail is that they lack accountability and visibility. A comment isn't a task; it's just text that the compiler ignores and your brain eventually filters out like background noise.
If it’s not in your backlog, it doesn’t exist.
How to Actually Make TODOs Work
If we want to stop treating our codebase like a graveyard of unfinished ideas, we need a system. Here is how I’ve started approaching it:
1. The "Linked Issue" Rule
Never write a TODO without a ticket number.
Bad: // TODO: Refactor this logic
Good: // TODO (PROJ-123): Refactor this logic to support multi-tenancy
If it’s not worth opening a quick GitHub issue or Jira ticket for, it’s probably not worth a TODO.
2. Use Tooling to Surface Them
Don't rely on your memory. Use extensions like Todo Tree in VS Code to visualize where these comments are hiding. Even better, you can use CI/CD hooks or "Todo Checkers" that fail a build (or just post a warning) if a TODO comment doesn’t follow a specific format.
3. Set an Expiration Date
Some teams use a "TTL" (Time to Live) for comments. If a TODO is older than 6 months, it either needs to be converted into a real story in the sprint or deleted. If the code has worked fine for 6 months without the change, do you really need it?
4. The "Stop the Bleeding" Approach
If you’re using a modern IDE, use annotations that actually stand out. Use FIXME for things that are actually broken and TODO for future enhancements. Make them high-contrast in your theme so they are impossible to ignore.
Better yet: Just do it now?
The best way to handle a TODO is to not write one. If the task takes less than 10 minutes, just fix it. The context-switching cost of coming back to it later is always higher than the cost of doing it now.
Final Thoughts
A codebase filled with stale TODOs is a sign of mounting technical debt and a lack of ownership. Let's stop treating our comments like a "later" bucket that never gets emptied.
How does your team handle TODOs? Do you let them rot, or do you have a system to keep the codebase clean? Let’s chat in the comments!
Enjoyed this? I originally wrote about this over on my blog here!
Top comments (0)