Cadmeo

JavaScript (JS) Beautifier

Minified or one-line source. Bundled output with mangled names will be readable, not restored.

Beautified

This cannot undo minification

Reindenting restores the layout, not the information. Minifiers rename variables to single letters, inline functions and drop comments, and none of that is recoverable. The original names no longer exist in the file. Where a source map is published, that is what actually restores the source.

The JS beautifier takes JavaScript that has been squeezed onto one line and puts the line breaks and indentation back, so you can read it. It restores the layout and nothing else, minification throws information away permanently, and no tool recovers it.

How it works

The source is walked character by character, tracking what it is inside. Braces open and close indentation levels; semicolons and top-level commas end lines; strings, template literals, comments and regular expression literals are copied through without being touched.

  • A semicolon inside a for(;;) header does not break the line, because the parentheses are still open.
  • A comma inside brackets keeps its arguments together; a comma at the top level of a declaration starts a new line.
  • A closing brace followed by else, catch, finally or while keeps them on the same line, which is how the construct reads.
  • A slash is treated as a regular expression only when what precedes it cannot end a value, after an operator, comma or opening bracket.

That last rule is a heuristic, and it is the one every non-parsing beautifier shares. Division and regular expressions are genuinely ambiguous in JavaScript without a full parse, so a line mixing them unusually can be misread.

Examples

A minified function

JS

function total(items){let sum=0;for(const i of items){...}return sum}

Result

Indented across multiple lines, with the for header intact

The semicolons inside the for header stay on their line; the ones ending statements break.

A regular expression

JS

const re=/a\/b/g;

Result

The literal is preserved, escaped slash and all

Recognising the slash as a regex start depends on the equals sign before it. Inside the literal, the escaped slash does not end it.

Bundled output

JS

Webpack output with single-letter names

Result

Readable layout, names still single letters

The structure becomes followable. What the variables meant is gone from the file and cannot be inferred.

Frequently asked questions

Can this recover the original source of a minified file?

No, and nothing can. Minifiers rename variables to single letters, inline functions and delete comments, that information is not in the file any more. What this restores is the layout, which makes the logic followable but leaves the names as they are.

What about source maps?

That is the real answer to unminification. A source map published alongside a bundle maps the minified code back to the original files, names and comments included. If a .map file is available, browser developer tools will use it and show you the actual source.

Why did it mangle a line containing division?

Because telling division from a regular expression literal needs a full parse, and this uses the same heuristic every non-parsing formatter uses: a slash after an operator or opening bracket starts a regex. An unusual expression can defeat that. If the output looks wrong, that is almost always why.

Does it change my code?

Only whitespace. No statements are added or removed, no semicolons inserted, nothing reordered. That also means it will not fix code that is already broken. A missing brace produces indentation that runs away rather than an error.

Will it format TypeScript or JSX?

Partially. Both are mostly JavaScript syntax, so braces and statements indent correctly, but JSX tags are not understood as markup and type annotations are treated as ordinary tokens. For either, a real formatter with a parser will do a much better job.