A safe, interactive, AST-based comment removal tool for Next.js, React, and TypeScript codebases.
Comment Cleaner scans your frontend project, classifies every comment it finds (directives, JSDoc, JSX comments, inline comments, dead code, TODOs, plain notes), and lets you remove them — one category at a time, one comment at a time, or all at once — without ever risking a broken build. Every change is backed up automatically and fully reversible.
▄████▄ ██▓ ▓█████ ▄▄▄ ███▄ █
▒██▀ ▀█ ▓██▒ ▓█ ▀▒████▄ ██ ▀█ █
▒▓█ ▄ ▒██░ ▒███ ▒██ ▀█▄ ▓██ ▀█ ██▒
▒▓▓▄ ▄██▒▒██░ ▒▓█ ▄░██▄▄▄▄██ ▓██▒ ▐▌██▒
▒ ▓███▀ ░░██████▒░▒████▒▓█ ▓██▒▒██░ ▓██░
C O M M E N T C L E A N E R
Stripping comments from a JS/TS codebase with regex is dangerous — it's very easy to accidentally mangle a string, a template literal, or a regex literal that merely looks like a comment. Comment Cleaner never touches raw text with regex-based deletion. It parses every file into a real AST with @babel/parser (the same parser family used by Babel and Next.js tooling), so it only ever sees genuine comment tokens.
- AST-accurate comment detection — TS, TSX, JS, JSX, MJS, CJS all supported.
- Smart classification into categories:
Category Example Default behavior Protected / directive /* eslint-disable ... */,@ts-ignore,@ts-expect-error,prettier-ignore, webpack magic comments,@license,SPDX-License-IdentifierNever removed, even in automatic mode Shebang #!/usr/bin/env nodeAlways protected JSDoc /** ... */above a function/classReviewable JSX comment {/* ... */}Detected and removed including the {}wrapperInline (trailing) type X = 1; // noteOnly the comment is stripped, code stays intact TODO / FIXME / HACK / NOTE // TODO: ...Reviewable as its own category Dead code (heuristic) // const x = 5;Flagged by heuristic, always shown before removal Standalone A comment alone on its own line Reviewable - Three review modes: category-by-category (recommended), fully manual (comment-by-comment with context), or fully automatic with a final confirmation.
- Abort anytime — type
abortat any prompt or hitCtrl+C; nothing is left half-written. - Automatic backups before touching any file, with a per-session manifest.
- One-command revert of an entire cleaning session, with hash-checking so files you've edited again since aren't silently overwritten.
- Atomic writes (write to temp file, then rename) — a crash mid-write can never corrupt a file.
- Post-write syntax verification — the cleaned file is re-parsed before it's saved; if it doesn't parse, nothing is written and the original stays untouched.
- Git awareness — warns if you're not in a repo or have uncommitted changes before starting.
- Zero runtime dependencies beyond
@babel/parser.
git clone https://github.com/mehranqadirian/comment-cleaner.git
cd comment-cleaner
npm installOr link it globally to use it from any project:
npm link
comment-cleaner clean --dir=/path/to/your/project# Interactive cleaning (defaults to the current directory)
node bin/cleaner.js clean
# Target a specific project
node bin/cleaner.js clean --dir=/path/to/your/nextjs-project
# List backup sessions
node bin/cleaner.js list --dir=/path/to/your/nextjs-project
# Revert the most recent (or a chosen) session
node bin/cleaner.js revert --dir=/path/to/your/nextjs-project
# Help
node bin/cleaner.js help- Review by category (recommended) — approve or reject an entire category at once (e.g. "remove all dead code"), or drop into manual mode for just that category.
- Fully manual — walk through every removable comment individually, with surrounding code shown for context.
- Fully automatic — every non-protected category is queued for removal; you still get one final confirmation showing the exact file/comment counts before anything touches disk.
- Git check — warns on a dirty working tree or a missing repo before doing anything.
- Backup-first — the original bytes of every file are copied to
.comment-cleaner-backups/<session-id>/...before it's modified. That directory ships with its own.gitignoreso it never gets committed. - Re-parse verification — after comments are stripped, the result is parsed again with the same parser; a syntax failure means the file is never written and is reported as failed.
- Atomic writes — temp file +
rename, so an interrupted write can never leave a corrupted file on disk. - Full revert —
comment-cleaner revertrestores an entire session. Files that were manually edited again after cleaning are skipped by default (pass--forceto override) so you never lose newer work. - AST-based removal, never regex — see Why this exists.
Drop a comment-cleaner.config.json in your project root to override any default from config/default.config.json:
{
"extensions": [".js", ".jsx", ".ts", ".tsx"],
"ignoreDirs": ["node_modules", ".next", "dist"],
"protectedPatterns": ["eslint-disable", "@ts-ignore", "my-custom-directive"],
"todoPatterns": ["TODO", "FIXME"],
"deadCodeHints": ["^(import|export)\\s", "console\\.log\\("]
}bin/cleaner.js CLI entry point, argument parsing
src/core/
scanner.js project walker, .gitignore-aware
commentParser.js AST parsing (@babel/parser) + comment extraction
classifier.js category rules (protected / jsdoc / jsx / dead code / ...)
remover.js computes safe deletion ranges and rewrites source
safeWriter.js atomic write + re-parse verification
backupManager.js session backups, manifest, revert
executor.js runs the cleaning plan file by file
analyzer.js ties scanner + parser + classifier together
src/cli/
interactiveMenu.js main interactive flow
revertFlow.js revert / list sessions flow
prompts.js readline helpers
src/ui/
theme.js colors and status flags ([SCANNING], [BACKUP], ...)
banner.js ASCII banner
quotes.js flavor text shown during operations
- CSS/SCSS comments are out of scope — only
.js/.jsx/.ts/.tsx/.mjs/.cjsare scanned. - Dead-code detection is a heuristic, not a guarantee; it's always shown before removal, never applied silently.
- Multi-line JSX comments where
{and}sit on separate lines from the comment are only partially supported.
The atmospheric one-liners printed during operations (src/ui/quotes.js) are original writing in a cinematic tone — not real movie dialogue, since reproducing actual film scripts is copyrighted content. Swap them for your own lines if you like; the ASCII banner is likewise an original design for this project.
Issues and PRs are welcome. Please run the existing manual test scenarios (clean → abort → clean → revert) against a scratch project before submitting changes to remover.js or backupManager.js, since correctness there is safety-critical.
MIT
