TODO Comments: The Silent Technical Debt Accumulator
May 2, 2026·8 min read·by Ihab Hamdy
TODO comments are the most insidious form of technical debt. They're visible
(you see them every time you open the file) but not actionable (there's no
ticket, no assignee, no deadline). Here's how to turn forgotten TODOs into
tracked work.
The TODO trap
You're refactoring a module. You find a section that needs a different approach
but would take another hour. You add a comment:
// TODO: refactor this to use the new auth module
You move on. The TODO stays in the code forever. Six months later, another
engineer sees the TODO, adds another TODO next to it, and now you have two
debts instead of one.
The problem: TODO comments are non-blocking. They don't fail CI. They don't
alert anyone. They're silently accumulating.
Most teams are surprised. A mid-size codebase (50k-100k lines) typically has
50-200 TODOs. Some teams have 500+. That's 500 pieces of unfinished work,
with no tracking, no assignee, and no plan.
Recommended for you
Turn TODOs into tracked work
Deviera scans your repos for TODO/FIXME comments and opens tickets automatically — so the debt stops hiding in code and starts getting triaged.
TODO comments are technical debt with three worst properties:
Visible but not actionable: Everyone sees them, no one owns them
Don't fail tests: Unlike type errors or broken builds, TODOs don't block anything
Compound over time: New TODOs are added faster than old ones are resolved
The result: a codebase that looks "working" but is accumulating hidden liabilities.
The automation solution
Here's how to turn TODOs into tracked work:
Detect TODOs automatically: Run a script that scans for TODO, FIXME, HACK comments
Parse the comment: Extract the TODO text and the file/line where it appears
Create a ticket: Generate a Linear/Jira ticket for each TODO
Track the debt: Include the ticket link in a code comment so it's easy to find
// TODO: refactor auth [DEBT-123] // This comment links to Linear task DEBT-123
What to track
Not all TODOs are equal. Prioritize:
Security TODOs: Anything related to auth, encryption, data handling
Performance TODOs: Known performance issues that could become problems
Architecture TODOs: Code that needs restructuring before it gets worse
Low priority: minor improvements, cleanup that can wait, nice-to-haves.
The debt triage
If you have hundreds of TODOs, you can't fix them all at once. Prioritize:
High impact: TODOs in frequently changed files
High risk: TODOs in security-critical code
Easy wins: Small TODOs that can be resolved quickly
Create a "technical debt" column in your backlog. Track how many TODOs you're
adding vs. resolving each week. The trend should be downward.
Working down a backlog you already have
Prioritisation advice assumes you are starting fresh. Most teams reading this are
not — they already have two hundred TODOs and no realistic path to zero. Declaring
TODO bankruptcy and deleting them all is tempting but throws away the one thing that
made them valuable: they mark places someone knowledgeable already identified as
wrong.
A more workable approach is to stop treating the backlog as a queue to drain and
start treating it as a map. Two rules do most of the work:
Fix TODOs in files you are already touching. If a pull request modifies a file containing a TODO, resolving it costs a fraction of what it would as standalone work, because the context is already loaded. This converts debt repayment into a side effect of normal delivery rather than a project competing for sprint capacity.
Age out the rest. A TODO nobody has touched in two years, in a file nobody has opened in two years, is not debt — it is archaeology. Delete it. If it mattered, it would have surfaced as a bug by now.
The combination shrinks the list without a dedicated cleanup sprint, and it
concentrates the effort on the code that is actually changing — which is the same
code most likely to break. TODOs in frequently modified files are the ones worth
paying down; TODOs in dormant files are noise that makes the real signal harder to see.
Preventing new TODOs
The best way to handle TODOs is to prevent them:
Require tickets for new TODOs: If you add a TODO, create the ticket first
Block CI on critical TODOs: Fail CI if TODO exists in security-related files
Make TODOs visible in standup: Add "any TODOs to discuss?" to your routine
A TODO without a ticket is just a wish. A TODO with a ticket is a plan.
Deviera's
CI Intelligence
watches commits for TODO, FIXME, HACK, and XXX comments and opens a structured
ticket in Linear, Jira, or ClickUp as they land — catching the debt at the moment
it is introduced, which is the only moment anyone still has the context to describe
it properly. See how it fits into the broader picture of
engineering friction measurement.
Frequently asked questions
Are TODO comments bad practice?
The comment itself is not the problem — abandoning it is. A TODO written next to the code it describes carries context that a ticket written a week later cannot reproduce: the exact line, the reason the shortcut was taken, and what the correct approach would be. What makes TODOs harmful is that they are non-blocking. Nothing fails, nobody is assigned, and no deadline exists, so they accumulate indefinitely. The fix is not banning them but pairing each one with a tracked ticket at the moment it is written.
How many TODO comments is too many?
There is no universal threshold, and chasing zero is usually wasted effort. The number that matters is the trend, not the total: are you adding TODOs faster than you resolve them? A codebase of 50,000 to 100,000 lines commonly carries 50 to 200, and a stable count with the risky ones tracked is healthier than a smaller count nobody is watching. Measure the ratio of TODOs added to TODOs closed each week — a consistently positive ratio means debt is compounding regardless of the absolute figure.
Should every TODO become a ticket?
No. Converting hundreds of TODOs into hundreds of tickets moves the clutter from your codebase into your backlog and makes both harder to read. Gate it on risk: security, authentication, data handling, and known performance problems justify a ticket immediately. Cosmetic cleanups and nice-to-haves are better left in code as comments. The useful question is not whether the TODO is real but whether anyone would ever prioritise it — if the answer is no, a ticket is just a slower way of ignoring it.
How do I find all the TODO comments in my repository?
A recursive grep such as `grep -rn "TODO\|FIXME\|HACK" --include="*.ts"` gives you the count and the locations in seconds, and it is the right first step because the number is usually higher than the team guesses. The limitation is that it is a snapshot: it tells you the state today and nothing about direction. To see the trend you need the scan to run on every commit, which is where automated detection at the commit level earns its place over a manual sweep.