JavaScript Beautifier — Format Minified JS Online
Break minified JavaScript or TypeScript onto separate lines so you can read it. Template literals, regular expressions and comments are recognised and kept intact. 100% client-side — your code stays private.
What does a JavaScript beautifier do? A JavaScript beautifier re-prints compressed source with line breaks and indentation so that statements, blocks and nesting become visible again. It is the inverse of minification, which removes those characters to shrink the file a browser downloads. Neither operation is meant to change what the code does — only the whitespace between tokens differs.
How to Use the JavaScript Beautifier
- Paste the code — Any JavaScript or TypeScript source, including a single compressed line from a production bundle. Formatting runs on every keystroke, so nothing needs to be submitted.
- Leave the action on Beautify — Beautify is the working direction of this tool. It splits the token stream at braces, semicolons and commas and adds one indent level per open brace.
- Choose an indent width — Two spaces matches the Airbnb and StandardJS conventions used across most React and Node projects; four spaces is common in older enterprise codebases. Tabs are also available.
- Scan the result for structure, not style — The value here is seeing where functions begin and end. Treat the exact spacing as approximate — run the output through Prettier or your editor's formatter if it is going into a repository.
- Watch the size badge — It compares input and output length. Beautifying adds characters, so the badge turns red and reports a gain — that is the expected direction, not an error.
-
Copy or download — Copy places the output on the clipboard; Download saves it as
formatted.jswith theapplication/javascriptMIME type.
How the Formatter Works
There is no abstract syntax tree behind this page. A scanner reads the source once, left to right, and labels each piece it recognises; the formatter then replays that stream and decides where to put line breaks. The scanner is the interesting part, because the constructs that trip up naive formatters are exactly the ones it is built to survive:
- Strings and template literals. Single quotes, double quotes and backticks are all consumed whole, with
\escapes honoured. Inside a template literal the scanner tracks${ … }interpolations by brace depth, so a brace inside an expression slot does not open a code block. - Regular expressions. A
/is treated as the start of a regex only when the preceding character makes a division impossible — after(,,,=, an operator or whitespace. Trailing flags such asgimsuyare absorbed with it. - Comments. Both
//to end of line and/* … */are recognised as single tokens, so punctuation inside a comment never affects layout. - Structure. Braces, parentheses, semicolons, commas and the
=>arrow each get their own token; identifiers and numbers are matched with the usual JavaScript rules.
Because the scanner cares about characters rather than grammar, TypeScript annotations, JSX-free ES modules, class fields and optional chaining all pass through as ordinary tokens instead of causing a parse error. That tolerance is the trade-off: the tool will happily format code that does not compile, and it cannot make any decision that requires knowing what an identifier means.
What Beautify emits
An opening brace increases the indent depth and starts a new line; a closing brace decreases it and is written on a line of its own; a semicolon ends the current statement and the next line is indented to the current depth. Commas get a following space, arrows get a space on each side, and a keyword is separated from whatever precedes it. On a compressed bundle that is enough to turn one 200-kilobyte line into something you can scroll through and search.
Token Reference
| Token | Recognised as | Effect on layout |
|---|---|---|
| Line comment | // to the next newline | Printed, followed by a line break |
| Block comment | /* to the next */ | Printed, followed by a line break |
| String | '…', "…", `…` with escapes and ${ } slots | Emitted verbatim, never reflowed |
| Regex | /…/ plus flags, when division is impossible in context | Emitted verbatim |
{ / } | Block or object braces | Depth + 1 / depth − 1, line break after |
; | Statement terminator | Line break, then indent to current depth |
, | Separator | Followed by a space |
=> | Arrow function | Spaced on both sides |
| Whitespace | Any run of spaces, tabs, newlines | Discarded; layout is regenerated from the tokens |
Do not run the output of this page in production. Two limits are worth stating plainly. The
Minify action drops every whitespace token, including the space that separates a keyword from an
identifier, so const total = a becomes consttotal=a and the result will not parse; with
Preserve Comments switched on it also keeps // comments without their line break, which
comments out everything after them. Beautify is usable for reading, but its indentation and
operator spacing are approximate rather than correct. Use this page to make compressed code legible, and use
Prettier, esbuild or terser in your build for anything you ship.
What a Production Minifier Actually Does
Removing whitespace is the smallest part of the job, and it is the part that matters least once a response is served with gzip or Brotli — compression already collapses long runs of repeated characters. The savings that change a bundle's size come from transformations that need a full syntax tree and scope analysis, which is why terser, esbuild and SWC parse the source rather than scanning it.
- Name mangling. Local bindings are renamed to one or two characters. This is only safe with scope analysis, because a minifier has to know that renaming
userAccounttoacannot collide with anything visible at that point, and that the name is not reached byevalor awithblock. - Dead code elimination. Branches that can never run — the
elseofif (true), a module export nobody imports — are removed. Tree shaking extends this across module boundaries using the static structure of ES imports. - Constant folding and inlining. Expressions with known values are evaluated at build time, and single-use functions are pasted into their call site.
- Source maps. A real minifier emits a
.mapfile recording where each output character came from, which is what lets DevTools show original filenames and line numbers in a stack trace.
The source map is the reason beautifying a bundle is a fallback rather than a first step. If the site you are debugging ships maps, DevTools will resolve a minified stack frame back to the original file, complete with the original variable names — information no beautifier can recover, because mangling threw it away. Beautifying is what you reach for when the maps are missing, when you are reading a third-party script, or when you only have a snippet pasted into a ticket.
Reading a bundle without a debugger
When you do have to work from beautified output, search rather than read. Minified code keeps string literals and property names intact, so an error message, an API path or a DOM selector from the failing behaviour will lead you to the relevant function far faster than scrolling. Once you are in the right region, the brace structure the formatter restored tells you where that function starts and ends, which is usually all you need to form a hypothesis.
Frequently Asked Questions
It handles them in the sense that it does not choke on them. Arrow functions, template literals with ${ } interpolation, destructuring, async/await, optional chaining, spread syntax and TypeScript type annotations are all scanned as ordinary tokens and survive the round trip. Because there is no parser, none of them are understood — the formatter cannot align a multi-line type or break a long chained call the way a language-aware tool would.
No, and this is the one thing to know before using that action. Whitespace in JavaScript is significant wherever it separates two identifier-like tokens, and the minifier discards it unconditionally: return value becomes returnvalue and let a = 1 becomes leta=1. Use it to see roughly how much of a file is whitespace and comments, not to produce a deployable asset. terser, esbuild and SWC do this correctly and take a single command to run.
The formatting never leaves the page — the scanner runs in JavaScript in your tab. Note, though, that the tool also writes the contents of the input box into the page URL so a session can be reloaded or bookmarked. If you have pasted proprietary source, an API key embedded in a config object, or anything else sensitive, clear the box before you copy or share that link.
Because minification strips newlines while that option keeps // line comments, and a line comment without its terminating newline swallows the rest of the file. It is a defect rather than a design choice. If you need to keep a licence header through a real build, terser's comments: 'some' option and esbuild's --legal-comments flag both preserve /*! … */ banners correctly.
A source map, whenever one exists. Maps let DevTools rewrite a minified stack frame back to the original file, line and variable names, which beautifying cannot do because name mangling destroyed those names. Reach for a beautifier when the map is missing or not published: third-party widgets, inline scripts, and snippets pasted into an issue. DevTools also has a built-in {} pretty-print button in the Sources panel that does the same job in place.
It will produce something readable, since JSON is a subset of JavaScript object syntax, but you will get better results from the JSON Formatter. That tool parses the document, so it validates the structure, reports the position of a syntax error, and preserves array formatting properly rather than inferring layout from punctuation.
Because spacing is decided from the previous token alone, without knowing whether a symbol is a binary operator, a unary operator or part of a compound assignment. That produces artefacts such as a double space after a comma or a missing space before =. The line and block structure is reliable; the horizontal spacing is not. Pass the result through Prettier if it is going into a codebase.
It still produces output. The depth counter increases on {, decreases on }, and is clamped at zero so it never goes negative. A missing closing brace leaves the remainder of the file indented one level too deep, which is a useful signal: the point where indentation stops matching your expectation is close to the brace that went missing.
It will re-line them, which helps, but obfuscation is a different problem from minification. Packers replace identifiers with meaningless names, hide strings in lookup arrays and encode control flow through dispatch loops. Restoring line breaks makes such code longer to scroll without making it much easier to follow; expect to trace behaviour with breakpoints rather than by reading.
Use Cases
Reading a Bundle With No Source Map
A production error points into main.4f2a.js and the .map file was never deployed. Paste the surrounding region here, restore the line breaks, and locate the failing function by searching for its string literals.
Auditing a Third-Party Script
Before adding a vendor tag to a page, expand the script it loads and skim what it touches — which endpoints it calls, whether it reads cookies or local storage, and what it attaches to the document.
Making a Pasted Snippet Legible
Someone drops a one-line snippet into a chat thread or a support ticket. Expand it so the whole team can read the same structure, instead of each person mentally re-indenting it.
Recovering an Inline Script
Copy a compressed <script> block out of a rendered page — a legacy CMS template, an email preview, a widget embed — and expand it into something you can port into a real source file.
Teaching How Tokens Work
Show a class that a formatter needs to know a string from a regex from a comment: paste code containing all three, then a template literal with a brace inside ${ }, and watch which characters count as structure.
Sizing Up Whitespace Before a Build Change
Run a source file through Minify and read the badge for a rough sense of how much of it is formatting and comments, as a sanity check before spending time configuring a bundler.