Developer Tools

API & Developer
Tools

The same 55-language comment removal engine, available as a REST API, npm package, and CLI. Zero dependencies. Works everywhere.

The engine ships as the open-source uncommenter package on npm and powers the same browser tool you can use directly. The parser is character-driven so it understands the difference between a comment and comment-like syntax inside template literals, regex literals, and Python docstrings.

For deeper context on the design and trade-offs, see the about page or browse the engineering blog.

REST API

Three endpoints. JSON in, JSON out. No API key required.

POST/api/v1/uncomment

Remove comments from source code. Supports all 55 languages with auto-detection.

Parameters

NameTypeRequiredDefaultDescription
codestringYesSource code to process
languagestringNoLanguage ID (e.g. "python"). Omit for auto-detection.
filenamestringNoFilename for extension-based detection
options.preserveDocstringsbooleanNotrueKeep docstrings (Python, Elixir)
options.preserveShebangsbooleanNotrueKeep shebang lines (#!/...)
options.preserveTodosbooleanNofalseKeep TODO/FIXME comments

Request

{
"code": "def hello():\n # comment\n print('hi')",
"language": "python",
"options": {
"preserveDocstrings": true,
"preserveTodos": false
}
}

Response

{
"processed": "def hello():\n print('hi')\n",
"language": "Python",
"commentsRemoved": 1,
"linesRemoved": 1
}
POST/api/v1/detect

Detect the programming language of source code using extension, shebang, and content analysis.

Parameters

NameTypeRequiredDefaultDescription
codestringYesSource code to analyze
filenamestringNoFilename for extension-based detection

Request

{
"code": "def hello():\n print('hi')",
"filename": "app.py"
}

Response

{
"language": "python",
"name": "Python",
"confidence": "high",
"extensions": [".py", ".pyw", ".pyi"]
}
GET/api/v1/languages

List all 55 supported languages with their comment syntax and features. Cached for 24 hours.

Response

{
"count": 55,
"languages": [
{
"id": "javascript",
"name": "JavaScript",
"extensions": [".js", ".jsx", ".mjs", ".cjs"],
"lineComment": ["//"],
"blockComment": [{ "start": "/*", "end": "*/" }],
"features": {
"hasRegexLiterals": true,
"shebangs": false,
"docstrings": false,
"nestedBlockComments": false,
"rawStrings": false
}
}
]
}

Try It

Test the API right here. Paste code, pick a language, hit Run.

Try it live

Code Examples

Call the API from any language.

curl -X POST https://uncommenter.com/api/v1/uncomment \
-H "Content-Type: application/json" \
-d '{
"code": "const x = 1; // comment\nlet y = 2; /* block */",
"language": "javascript"
}'

npm Package

Import the engine directly. Zero runtime dependencies. CJS + ESM + full TypeScript definitions.

$ npm install uncommenter

Quick Start

import { uncomment } from "uncommenter";
const result = uncomment(
'const x = 1; // this is a comment',
'javascript'
);
console.log(result.processed); // "const x = 1;\n"
console.log(result.commentsRemoved); // 1
console.log(result.language); // "JavaScript"

Auto-Detection

import { uncomment, detectLanguage } from "uncommenter";
// Detect by filename extension
const result = uncomment(code, undefined, "app.py");
// Detect by content analysis
const lang = detectLanguage(code);
console.log(lang.name); // "Python"

Low-Level Parser

import { removeComments, languageMap, DEFAULT_OPTIONS } from "uncommenter";
const config = languageMap.get("python")!;
const { result, commentsRemoved } = removeComments(
source,
config,
{ ...DEFAULT_OPTIONS, preserveTodos: true }
);

Exports

// Functions
export { uncomment } from "uncommenter";
export { removeComments } from "uncommenter";
export { detectLanguage, detectByExtension, detectByShebang, detectByContent } from "uncommenter";
// Data
export { languages, languageMap, extensionMap } from "uncommenter";
// Types
export type { LanguageConfig, UncommentOptions, UncommentResult } from "uncommenter";
export { ParserState, DEFAULT_OPTIONS } from "uncommenter";

CLI

Strip comments from files and directories right from your terminal.

$ npm install -g uncommenter

Commands

# Process a single file in-place
uncommenter src/app.ts
# Write to output file
uncommenter src/app.ts -o clean/app.ts
# Recursive directory processing
uncommenter src/ -r
# Pipe mode (stdin to stdout)
cat main.py | uncommenter --stdin -l python
# Show colored diff (no changes written)
uncommenter src/app.ts --diff
# Preview what would change
uncommenter src/ -r --dry-run
# List all 55 supported languages
uncommenter languages

Flags

FlagDescription
-r, --recursiveProcess directories recursively
-l, --language <lang>Force language (skip auto-detection)
-o, --output <path>Write output to file
-d, --diffShow colored diff
--dry-runPreview changes without writing
--stdinRead from stdin, write to stdout
-g, --glob <pattern>Filter files by extension
--exclude <dirs>Comma-separated dirs to exclude
--preserve-docstringsKeep docstrings (default: true)
--no-preserve-docstringsRemove docstrings
--preserve-todosKeep TODO/FIXME comments
--preserve-shebangsKeep shebangs (default: true)
--no-preserve-shebangsRemove shebangs

Config File

Create a .uncommenterrc file in your project root:

.uncommenterrc
{
"preserveDocstrings": true,
"preserveShebangs": true,
"preserveTodos": false,
"exclude": ["node_modules", "dist", ".git", "vendor"]
}

Real-World Examples

# Clean up a TypeScript project before shipping
uncommenter src/ -r -g "*.ts" --no-preserve-docstrings
# Preview changes to Python files, keeping TODOs
uncommenter lib/ -r -g "*.py" --preserve-todos --diff
# Process a single file, output to new location
uncommenter legacy/app.js -o clean/app.js
# Pipe through in a shell script
cat input.sql | uncommenter --stdin -l sql > clean.sql
# Clean everything except tests
uncommenter src/ -r --exclude "tests,__mocks__"

Errors & Limits

Error Responses

CodeErrorDescription
400Bad requestMissing or invalid "code" field, or unknown language
413Payload too largeCode exceeds 1MB limit
429Too many requestsRate limit exceeded (100 req/min)
500Internal server errorProcessing failed unexpectedly

Rate Limiting

The API is rate-limited to 100 requests per minute per IP. Rate limit headers are included in every response:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 1706745600

When the limit is exceeded, you'll receive a 429 response with a Retry-After header indicating when you can retry.

Limits

LimitValue
Max request body1 MB
Rate limit100 requests / minute
Languages supported55
API key requiredNo
CORSAll origins allowed