GitHub - jbreckmckye/todo-or-else: Enforce deadlines on TODO / FIXME comments

4 min read Original article ↗

Enforces deadlines on code TODO comments

Description

This command-line program scans files for TODO / FIXME comments and fails your CI build if any:

  • have an expired deadline (by: tag is a date in the past)
  • are too old (from: tag older than staleness threshold - default 90 days)
  • have invalid or missing tags

Give your TODO comments a deadline or created date like so:

// TODO (by:2025-09-25) add logging
//      ^^^^^^^^^^^^^^^ deadline

# FIXME (from:2026-01-01) refactor these tests
//      ^^^^^^^^^^^^^^^^^ created date

/* TODO (by:2028-01)
 * rewrite it in rust
 */

Then, in your CI build, todo-or-else will fail when TODOs go overdue:

$ todo-or-else scan ./src ./lib

 TODO SCAN RESULTS

src/components/User.tsx (2 items)
  45:0   ⚠ DEADLINE EXPIRED: 2025-09-25
         TODO (by:2025-09-25) add logging
  30:4   ⚠ TOO OLD: 2026-01-01
         # FIXME (from:2026-01-01) refactor these tests

────────────────────────────────────────────────────────────────────────────────
Scanned 104 files • Found 2 issues • 15 TODOs
✨ Done in 42ms

Todo or else is written in Go for portability and performance, and uses Tree Sitter to parse code fast and accurately. No Regex guessing here.

Why?

Developers like to leave TODO and FIXME comments but never go back to actually complete the work.

Put this in your CI pipeline (example: CircleCI, Github Actions workflows) and builds will fail if a TODO goes out of date.

This creates a way you can be flexible in the short term but confident that things will be revisited.

Languages supported

✅ CSS                    ☑️ LESS*             ✅ TypeScript/TSX
✅ Dockerfile             ✅ Python                 
✅ Golang                 ☑️ SASS/SCSS*     
✅ JavaScript/JSX         ✅ Shell

*= beta support

(Need more? Consider raising an issue)

TODO format

  • TODO comments must have TODO or FIXME (case-insensitive)
  • then follows a parenthesised list of "tags"
  • tags are comma separated key:value pairs
  • then follows the task itself

For example

TODO (by:2027-03, owner:Fran) do something

Date formats

Format Meaning
TODO (by:2025-09-25) Deadline: exact date
TODO (by:2025-09) Deadline: last day of month
TODO (from:2025-01-15) Created date (checked for staleness)

TODOs must have either a by: (deadline) or from: (created date) tag.

Installation

Homebrew (macOS/Linux)

brew install jbreckmckye/formulae/todo-or-else

Download binary

Download from GitHub Releases.

Usage

Scan (CI enforcement)

Scans directories for TODOs and exits with error if any are invalid or expired:

$ todo-or-else scan <DIRS>

FLAGS   --stale-age INT   Days until a TODO with a from: tag is considered stale (default: 90)

It uses GoCodeWalker to apply .gitignore rules.

Example:

$ todo-or-else scan .

 TODO SCAN RESULTS

src/components/User.tsx (2 items)
  30:4   ✗ TAG VALUES: invalid deadline, must be YYYY-MM-DD or YYYY-MM
         // TODO (by:soon) add logging
  45:8   ⚠ DEADLINE EXPIRED: 2025-01-15
         // FIXME (by:2025-01-15) refactor this

────────────────────────────────────────────────────────────────────────────────
Scanned 104 files • Found 2 issues • 15 TODOs
✨ Done in 42ms

List (view TODOs)

Lists all TODOs without enforcement:

$ todo-or-else list <DIRS>

Example:

$ todo-or-else list src

 TODOS

internal/core/scan.go (1 items)
  15:4   // TODO (by:2026-03-01) add logging

internal/parser/parse.go (2 items)
  56:8   // FIXME (2026-06) refactor tests
  128:4  // TODO (from:2025-01-01) clean this up

✨ Done in 28ms

Common patterns

# Scan files in src and lib directories
todo-or-else scan ./src ./lib

# List all TODOs in current directory
todo-or-else list .

# Mark TODOs as stale after 30 days (instead of default 90)
todo-or-else scan ./src --stale-age 30

FAQ

How stable is this?

It's tested, but in Beta. Please report any bugs you think you've seen.

I want support for another language!

Consider raising a pull request to add a new language parser.

What stops me just delaying indefinitely?

What stops you deleting your whole test suite, stealing the company credit card and going on a bender to Vegas?

You still need some discipline, but at least with this, you can use TODO messages knowing they won't be forgotten.

How fast is it?

Pretty fast. On up-to-date machines it can go through a few thousand source files in just a couple of seconds. The underlying parser (Tree Sitter) is written in C.