JavaScript Prettier - format, beautify and unminify JS in your browser
A JavaScript formatter takes source that is minified, hand-indented or pasted out of a chat window and prints it again in one consistent style. This one works the way your editor does: it parses the code into a real syntax tree and prints that tree from scratch, so the layout is decided by the structure of the program rather than by counting braces. Everything happens inside your own browser tab, so nothing is uploaded.
Why an AST-based beautifier beats a regex one
JavaScript is full of places where a character means different things depending on context. A slash can open a regular expression or divide two numbers. A brace can open a block, an object literal or a destructuring pattern. // inside a string is not a comment, and a template literal can contain anything at all, including the braces and newlines a naive beautifier would try to reindent. Parsing the file properly is what lets the printer keep arrow functions, classes, class fields, private #members, static blocks, generators, async/await, optional chaining, nullish coalescing, logical assignment, BigInt and JSX intact.
The same parse gives you a free syntax check. Paste something broken and you get the exact line, the exact column and a caret under the token that confused the parser, which is usually faster than waiting for a build to fail.
Unminifying a bundle, and what that can and cannot do
Feeding a one-line bundle to Unminify mode restores line breaks, indentation and blocks, so the code becomes browsable and can be stepped through in a debugger. Turning on Expand bodies also puts braces round single-statement if, for and while bodies, which is what makes a dense loop readable.
userAccountId to e and threw the original away, so no beautifier can bring it back. Comments are gone for the same reason - and nothing here is de-obfuscated or unpacked.The options, and what they actually change
Print width is a target rather than a hard limit: the printer fits what it can on a line and breaks the rest, so lowering it to 40 is the quickest way to see a long promise chain break one call per line. Indent style and size, semicolons, quote style and trailing commas are the settings teams argue about; choosing them here and exporting the matching .prettierrc ends the argument with a file instead of an opinion. Trailing commas set to all keep version-control diffs to a single line when an argument list grows. Switching semicolons off does not introduce ASI bugs, because the printer adds the leading semicolon a line starting with ( or [ needs.
Three options rewrite rather than reprint: sorting imports, removing comments and dropping blank lines. Each works from parser positions, each is re-parsed afterwards, and each is skipped with a warning if the result would not parse. Side-effect imports such as import "./polyfill.js" are never moved past another import, because that would change the order modules run in.
Modules, CommonJS and the ECMAScript target
The tool reads the file and tells you what it is: an ES module if it uses import, export, import.meta or top-level await, a script otherwise, and CommonJS when it finds require or module.exports. Declaring the type yourself turns that into a check, so mixing require into a file you call a module is reported rather than discovered at runtime.
The ECMAScript target works the same way. The parser always accepts the newest grammar, so the target does not change the output - it lists every construct above the level you chose, with the edition that introduced it and the line it is on. Setting it to ES2015 is a fast way to find the optional chains and class fields an old browser or a strict build step would reject.
Proof that the formatting is safe
Reformatting should never change behaviour, so the tool checks rather than assumes. After printing, the output is parsed again and compared node by node with the source that was printed. Quoted object keys, the empty statements a leading semicolon creates, JSX whitespace and comments are normalised away because Prettier is entitled to change those; anything else that differs is shown as a warning instead of being handed back quietly. Reading the diff view before you copy is still worthwhile - it says exactly how many lines were touched, added and removed.