task-comment-format
July 19, 2026 · View on GitHub
Targeted pattern scope
This rule checks TODO-style task comments that start with markers such as
TODO, FIXME, XXX, or HACK.
It applies to line comments, block comments, and JSDoc-style comment text after
block-comment decoration is normalized. Tool-control comments such as
eslint-disable and TypeScript suppression comments are ignored.
What this rule reports
This rule reports task comments that stop at the marker or only contain recognized owner or issue metadata without any descriptive prose.
By default, comments like TODO, FIXME:, HACK (legacy), or
TODO [#123] are invalid because they record that something is wrong without
explaining what should happen next. Parenthesized or bracketed multiword text,
such as (This is broken) or [Needs redesign], remains descriptive prose
instead of being discarded as metadata.
Why this rule exists
Bare task comments create maintenance debt. They signal unfinished work, but they do not tell future readers what needs to change or why the task still matters.
Requiring a short descriptive body makes task comments more actionable during code review, easier to search for later, and less likely to become permanent noise.
❌ Incorrect
// TODO
startServer();
// FIXME:
retryRequest();
/* HACK (legacy) */
enableFallback();
// TODO @jane #123
removeFallback();
✅ Correct
// TODO: remove the temporary fallback after the API v2 rollout.
startServer();
// FIXME(jane): handle null input from the partner API.
retryRequest();
/* HACK [PROJ-123]: keep this branch until the cache bug is fixed upstream. */
enableFallback();
// TODO: (This is broken)
repairFallback();
// TODO [Needs redesign]
redesignFallback();
Behavior and migration notes
- The rule is report only. It does not rewrite task comments for you.
- Optional metadata matching the grammar below is allowed, but metadata alone is not enough.
- The default markers are
TODO,FIXME,XXX, andHACK. - Directive comments such as
// eslint-disable-next-line ...are ignored.
Accepted metadata grammar
The rule uses deterministic token validation. It does not try to infer meaning from natural language. The accepted metadata grammar is:
metadata = parenthesized-owner | bracketed-issue | handle | issue
parenthesized-owner = "(", ["@"], owner, ")"
bracketed-issue = "[", issue, "]"
handle = "@", owner
issue = hash-issue | keyed-issue
hash-issue = "#", digit, {digit}
keyed-issue = ascii-letter, {ascii-letter | digit}, "-", digit, {digit}
owner = owner-edge | owner-edge, {owner-character}, owner-edge
owner-character = owner-edge | "." | "-"
owner-edge = ascii-letter | digit | "_"
ascii-letter = "A" ... "Z" | "a" ... "z"
digit = "0" ... "9"
Each metadata token must end at the comment end, whitespace, or a supported
separator (:, -, or —). Multiple metadata tokens must be separated by
whitespace or a supported separator. A parenthesized owner may immediately
follow the task marker, as in FIXME(jane). Separators may appear between the
marker, metadata, and prose.
Consequently, the following prefixes are recognized and stripped before the description-length check:
(jane)and(@jane)@jane#123andPROJ-123[#123]and[PROJ-123]
Empty, multiword, malformed, or unclosed delimiters are not metadata. Neither
are partial issue references such as #123abc or PROJ-123abc. Those strings
remain part of the descriptive text and are evaluated against
minDescriptionLength like any other prose.
Additional examples
Customize the accepted task markers and minimum description length:
import writeGoodComments from "eslint-plugin-write-good-comments-2";
export default [
{
plugins: {
"write-good-comments": writeGoodComments,
},
rules: {
"write-good-comments/task-comment-format": [
"error",
{
minDescriptionLength: 12,
terms: ["TODO", "NOTE"],
},
],
},
},
];
ESLint flat config example
import writeGoodComments from "eslint-plugin-write-good-comments-2";
export default [
{
files: ["**/*.{ts,tsx,js,jsx}"],
plugins: {
"write-good-comments": writeGoodComments,
},
rules: {
"write-good-comments/task-comment-format": "error",
},
},
];
When not to use it
Do not use this rule if your team bans TODO-style comments entirely with a rule
such as eslint/no-warning-comments or if all follow-up work must live only in
an external issue tracker.
If your team keeps task comments, this rule works best when you want them to be descriptive instead of bare markers.
Package documentation
This rule complements related task-comment tooling:
Rule catalog ID: R002