ESLint InterlaceESLint Interlace
Plugin: conventionsRules

expiring-todo-comments

ESLint rule documentation for expiring-todo-comments

๐Ÿ“ก Live from GitHub โ€” This documentation is fetched directly from expiring-todo-comments.md and cached for 6 hours.

Keywords: TODO, FIXME, XXX, expiration, comments, technical debt, code quality, ESLint rule, version, date, LLM-optimized

Add expiration conditions to TODO comments to prevent forgotten tasks. This rule is part of eslint-plugin-conventions and provides LLM-optimized error messa

Add expiration conditions to TODO comments to prevent forgotten tasks. This rule is part of eslint-plugin-conventions and provides LLM-optimized error messages.

Quick Summary

AspectDetails
SeverityWarning (code quality)
Auto-FixโŒ No (requires addressing the TODO)
CategoryQuality
ESLint MCPโœ… Optimized for ESLint MCP integration
Best ForTeams tracking technical debt, version-based deprecations

Rule Details

Why This Matters

IssueImpactSolution
๐Ÿ“… Forgotten TODOsTechnical debt accumulatesAdd expiration dates
๐Ÿ”„ Version MigrationOld workarounds stayVersion-based conditions
๐Ÿ“ฆ Dependency UpdatesPolyfills become unnecessaryPackage-based conditions
โฐ Deadline TrackingTasks slip through reviewsDate-based conditions

Configuration

OptionTypeDefaultDescription
termsstring[]['TODO', 'FIXME', 'XXX']Terms to check for
dateFormatstring'YYYY-MM-DD'Date format for expiry dates

Condition Types

Condition TypeFormatExample
Date[YYYY-MM-DD]TODO [2025-01-01]: Remove this
Package Version[>=X.Y.Z]TODO [>=2.0.0]: Use new API
Engine Version[engine:node@>=X]TODO [engine:node@>=20]: Use fetch
Dependency[+package] / [-package]TODO [+lodash]: Replace with lodash

Examples

โŒ Expired (Will Report)

// Date-based expiration (if current date >= 2024-12-01)
// TODO [2024-12-01]: Remove deprecated API call
fetchLegacyData();

// Version-based expiration (if package.json version >= 2.0.0)
// FIXME [>=2.0.0]: Migrate to new authentication system
useOldAuth();

// Engine-based expiration (if node >= 20)
// TODO [engine:node@>=20]: Replace node-fetch with native fetch
import fetch from 'node-fetch';

// Dependency-based (if lodash is installed)
// TODO [+lodash]: Use _.debounce instead
function debounce() { /* custom impl */ }

โœ… Not Yet Expired

// Future date
// TODO [2030-01-01]: Consider removing this feature
legacyFeature();

// Future version
// FIXME [>=10.0.0]: This will need updating
currentImplementation();

โŒ Invalid Format

// Missing brackets
// TODO 2024-12-01: Fix this  // โŒ Invalid

// Wrong date format
// TODO [12/01/2024]: Fix this  // โŒ Invalid

// Multiple conditions
// TODO [2024-01-01, >=2.0.0]: Fix this  // โŒ Invalid

Configuration Examples

Basic Usage

{
  rules: {
    'conventions/expiring-todo-comments': 'warn'
  }
}

Custom Terms

{
  rules: {
    'conventions/expiring-todo-comments': ['warn', {
      terms: ['TODO', 'FIXME', 'XXX', 'HACK', 'BUG']
    }]
  }
}

Strict Mode

{
  rules: {
    'conventions/expiring-todo-comments': ['error', {
      terms: ['TODO', 'FIXME']
    }]
  }
}

Use Cases

Version Migrations

// When you're waiting for a major version to remove compatibility code
// TODO [>=3.0.0]: Remove React 17 compatibility layer
if (React.version.startsWith('17')) {
  // legacy code
}

Node.js Feature Adoption

// Waiting for minimum Node version in CI
// TODO [engine:node@>=18]: Use native fetch instead of node-fetch
import fetch from 'node-fetch';

// TODO [engine:node@>=20]: Use native test runner
import { describe, it } from 'node:test';

Scheduled Deprecations

// Time-boxed technical debt
// TODO [2025-06-01]: Remove this after Q2 migration
function legacyApiHandler() { }

Dependency Additions

// Waiting for a package to be added
// TODO [+zod]: Replace with zod validation
function validateManually(data: unknown) { }

When Not To Use

ScenarioRecommendation
๐Ÿ“ Regular TODOsThis rule only affects conditional TODOs
๐Ÿ”„ No release cycleDate conditions work without versions
๐Ÿงช PrototypingDisable during rapid development

Comparison with Alternatives

Featureexpiring-todo-commentsunicorn ruleManual tracking
Date conditionsโœ… Yesโœ… YesโŒ No
Version conditionsโœ… Yesโœ… YesโŒ No
Engine conditionsโœ… Yesโœ… YesโŒ No
LLM-Optimizedโœ… YesโŒ NoโŒ No
ESLint MCPโœ… OptimizedโŒ NoโŒ No

Further Reading

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Dynamic Variable References

Why: Static analysis cannot trace values stored in variables or passed through function parameters.

// โŒ NOT DETECTED - Value from variable
const value = externalSource();
processValue(value); // Variable origin not tracked

Mitigation: Implement runtime validation and review code manually. Consider using TypeScript branded types for validated inputs.

Imported Values

Why: When values come from imports, the rule cannot analyze their origin or construction.

// โŒ NOT DETECTED - Value from import
import { getValue } from './helpers';
processValue(getValue()); // Cross-file not tracked

Mitigation: Ensure imported values follow the same constraints. Use TypeScript for type safety.

On this page

No Headings