Conservative local compactor
Safe JavaScript Minifier
Remove comments and unnecessary horizontal whitespace from a deliberately limited JavaScript subset. Unsupported syntax is refused instead of guessed, and your source never leaves this page.
Know the boundary: this tokenizer preserves line breaks for automatic semicolon insertion and never executes your code. It refuses regex literals, division operators, interpolated templates, private fields, JSX, TypeScript-like angle syntax, Unicode identifiers, BigInt, and numeric separators. Its fail-closed angle check also refuses every plain < operator (while <= remains supported). Use a parser-backed build tool for production projects.
JavaScript input
Limit: 120,000 UTF-16 code units. The input must already be valid ECMAScript within the documented subset.
0 / 120,000 code units
Compacted output
No current result. Minify a supported snippet to see exact UTF-8 measurements.
This output is lexical compaction only. It has not been executed or fully parsed.
- No safety report yet.
What this JavaScript minifier safely changes
The tool recognizes a bounded set of lexical tokens. It removes ordinary line and block comments, optionally retains common license/preserve block comments, and removes horizontal whitespace when adjacent tokens cannot fuse. It preserves a line feed whenever the original gap contained any ECMAScript line terminator, including one inside a multiline comment. That conservative rule protects automatic semicolon insertion cases such as a newline after return or before postfix ++.
Quoted strings and no-substitution template literals are copied exactly. Decimal and 0x/0o/0b Number literals are recognized, with required spacing retained between a number and a following dot. Parentheses, brackets, and braces are checked for balance. Nothing is renamed, evaluated, reordered, folded, or deleted as dead code.
Why valid-looking code may be refused
ECMAScript uses different lexical goals to decide whether / begins division or a regular-expression literal. Template substitutions similarly switch between template and expression grammars. A tokenizer without a parser cannot safely infer every case, so this tool rejects every non-comment slash and every ${...} template. Private identifiers, escaped or non-ASCII identifiers, BigInt, numeric separators, decorators, legacy HTML comments, JSX, and angle-bracket type syntax are also outside the supported subset. To catch angle syntax without parsing, it rejects every plain < operator; the distinct <= punctuator remains supported.
A refusal is not a claim that the source is invalid. It means the snippet needs a real ECMAScript parser or falls outside this deliberately small safety contract. Conversely, a successful result does not prove the source is syntactically correct or behaviorally equivalent; it only means the tokenizer found no known unsupported lexical hazard and made its limited transformations.
How to interpret the size numbers
Transfer size is shown as UTF-8 bytes using TextEncoder when available, rather than JavaScript string length. “Saved” compares the pasted source with the current output before HTTP compression. Gzip or Brotli, source maps, bundling, module loading, caching, and server headers can change real delivery cost, so these figures are a local pre-compression comparison—not a performance forecast.
Production use, privacy, and standards
For deployed applications, prefer the pinned parser-backed minifier already used by the project and run its tests. This page is useful for conservative snippets, learning, and preflight comparison; it is not a replacement for Terser, esbuild, Rollup, webpack, or a compiler pipeline. Review the ECMAScript lexical grammar and MDN lexical grammar guide for the underlying hazards.
Source, output, metrics, copying, and file creation stay in this browser tab. The tool makes no input-bearing request, upload, storage, cookie, session, database, analytics, or shared-state call of its own. Shared site infrastructure may deliver this page and record an ordinary page view, but this tool does not expose the editor contents to it.