Prettier, without installing anything
This page runs Prettier with its Babel parser, so it accepts everything modern JavaScript allows: ES modules, classes with #private fields, optional chaining, ??=, top-level await, async iterators, and JSX for React, Preact and Solid components. Output is identical to npx prettier --write with the same options, which makes it useful for checking what a team style will do before adding it to a project, or for tidying a snippet before pasting it into a pull request comment.
Typical inputs: a function copied out of browser DevTools, a bookmarklet, a code sample from a Stack Overflow answer with tabs and spaces mixed, a userscript, or a bundle you need to read while debugging a production issue.
How to use it
Paste code or drop a .js, .mjs, .cjs or .jsx file. Ctrl/Cmd+Enter formats; Ctrl/Cmd+Shift+M minifies; Ctrl/Cmd+Shift+C copies the result; Ctrl/Cmd+K opens the command palette. A syntax error stops formatting and is shown with its line and column, so the page also works as a quick syntax check.
Code pasted here is parsed by JavaScript running in your own tab. API keys hard-coded in a script you are debugging do not end up in someone else’s server logs.
Options, in Prettier terms
- Semicolons (Prettier
semi): on adds a semicolon after every statement. Off removes them, and Prettier then inserts a defensive;before any line starting with(,[or a template literal, where automatic semicolon insertion would otherwise join two lines. - Single quotes (
singleQuote): use'instead of"for strings. A string containing more of the preferred quote than the other keeps the quote that needs fewer escapes. JSX attributes always use double quotes. - Trailing commas (
trailingComma): All adds them wherever multi-line syntax allows, including function parameters and calls. ES5 limits them to arrays and objects, for code that must run on engines older than ES2017. None removes them. - Spaces inside { } (
bracketSpacing):{ total }versus{total}in object literals, destructuring and imports. - Arrow function parentheses (
arrowParens): Always writes(order) => order.total; Avoid writesorder => order.totalwhen there is exactly one simple parameter.
Indent (spaces or tabs) and line width (Prettier’s printWidth) apply too. Mirror your project’s .prettierrc values here to preview exactly what a commit hook would produce.
Minifying and unminifying
Minify uses Terser with two compression passes and name mangling, and removes comments. If the code contains import or export, it is treated as an ES module, which allows top-level names to be mangled too. JSX cannot be minified directly because Terser only understands standard JavaScript; compile it with your bundler first.
Beautifying a minified bundle restores indentation and line breaks, but not what minification threw away: mangled names like e, t and n stay short, and comments are gone. For real debugging, a source map gives you the original files. Formatting is still the fastest way to see the structure of a third-party script you cannot get the source for.
Code with type annotations is not plain JavaScript. Use the TypeScript formatter for .ts and .tsx files.
Examples
Minified analytics snippet
A one-line loader becomes readable, showing the IIFE structure and the deferred queue processing.
!function(w,d){var q=w.shopTrack=w.shopTrack||[];if(q.loaded)return;q.loaded=!0;var s=d.createElement("script");s.async=!0;s.src="https://cdn.example.com/track.js";s.onload=function(){q.forEach(function(e){w.shopTrack.send(e)})};d.head.appendChild(s)}(window,document);!(function (w, d) {
var q = (w.shopTrack = w.shopTrack || []);
if (q.loaded) return;
q.loaded = !0;
var s = d.createElement("script");
s.async = !0;
s.src = "https://cdn.example.com/track.js";
s.onload = function () {
q.forEach(function (e) {
w.shopTrack.send(e);
});
};
d.head.appendChild(s);
})(window, document);
Express route in a no-semicolon, single-quote style
Semicolons are dropped, strings switch to single quotes, and the long schema object is wrapped with ES5-style trailing commas.
import express from "express";
import { z } from "zod";
const router = express.Router();
const RefundBody = z.object({ orderId: z.string(), amount: z.number().positive(), reason: z.enum(["damaged","late","other"]) });
router.post("/refunds", async (req, res, next) => { try { const body = RefundBody.parse(req.body); const refund = await req.app.locals.payments.refund(body.orderId, { amount: body.amount, reason: body.reason }); res.status(201).json({ id: refund.id, status: refund.status }); } catch (err) { next(err); } });
export default router;import express from 'express'
import { z } from 'zod'
const router = express.Router()
const RefundBody = z.object({
orderId: z.string(),
amount: z.number().positive(),
reason: z.enum(['damaged', 'late', 'other']),
})
router.post('/refunds', async (req, res, next) => {
try {
const body = RefundBody.parse(req.body)
const refund = await req.app.locals.payments.refund(body.orderId, {
amount: body.amount,
reason: body.reason,
})
res.status(201).json({ id: refund.id, status: refund.status })
} catch (err) {
next(err)
}
})
export default router
React component with JSX
JSX is laid out like HTML, and single-parameter arrow functions such as item => … lose their parentheses.
export function OrderSummary({order,onCancel}){const total=order.items.reduce((sum,item)=>sum+item.qty*item.price,0);return <section className="order-summary"><h2>Order {order.id}</h2><ul>{order.items.map(item=><li key={item.sku}>{item.qty} × {item.name}</li>)}</ul><p>Total: {total.toFixed(2)}</p>{order.status==="paid"&&<button onClick={()=>onCancel(order.id)}>Cancel order</button>}</section>}export function OrderSummary({ order, onCancel }) {
const total = order.items.reduce(
(sum, item) => sum + item.qty * item.price,
0,
);
return (
<section className="order-summary">
<h2>Order {order.id}</h2>
<ul>
{order.items.map(item => (
<li key={item.sku}>
{item.qty} × {item.name}
</li>
))}
</ul>
<p>Total: {total.toFixed(2)}</p>
{order.status === "paid" && (
<button onClick={() => onCancel(order.id)}>Cancel order</button>
)}
</section>
);
}
Utility module minified with Terser
The ES module is compressed and its local variables are mangled, while the exported names stay intact.
/**
* Formats an amount in minor units (cents) as a currency string.
*/
export function formatMoney(amountInCents, currency = "USD", locale = "en-US") {
const formatter = new Intl.NumberFormat(locale, { style: "currency", currency });
return formatter.format(amountInCents / 100);
}
export function sumLineItems(items) {
return items.reduce((total, item) => total + item.quantity * item.unitPriceCents, 0);
}
export function formatMoney(e,n="USD",r="en-US"){return new Intl.NumberFormat(r,{style:"currency",currency:n}).format(e/100)}export function sumLineItems(e){return e.reduce((e,n)=>e+n.quantity*n.unitPriceCents,0)}Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
Unexpected tokenExplained | The parser reached a character that cannot appear there: a missing closing brace, a stray operator, or TypeScript syntax such as a type annotation in a .js file. | Look at the reported position and just before it. If the code contains types, switch to the TypeScript formatter. |
Unterminated string constant. | A quote inside a string ended it early, as in ‘it’s’, or a string was broken across lines without a backslash. | Escape the inner quote (‘it's’), switch the outer quotes (“it’s”), or use a template literal for multi-line text. |
Unterminated template. | A template literal opened with a backtick has no closing backtick, often because a ${…} expression contains a stray backtick. | Add the closing backtick at the end of the template. |
Unexpected token, expected "," | Items in a parameter list, array or object are not separated properly, or a bracket is missing so the parser is still inside the list. | Add the missing comma or closing bracket near the reported position. |
Minifying JSX is not supported — compile JSX to JavaScript first | Terser only accepts standard JavaScript, and JSX tags are a syntax extension. | Beautify JSX here, but minify the compiled output from esbuild, Vite, Babel or your framework’s build. |
Frequently asked questions
Is this the same as running Prettier?
Yes. It is Prettier 3 with the Babel parser, so the same options produce the same output as the Prettier CLI or editor extension.
Can I get readable code back from a minified file?
Formatting restores indentation and line breaks, so the control flow is easy to follow. Original variable names and comments cannot be recovered without the source map.
Does the formatter run my code?
No. The code is parsed into a syntax tree and printed again; it is never executed. It is also not uploaded.
Why did Prettier add a semicolon at the start of a line?
With Semicolons turned off, a line starting with (, [ or ` would be joined to the previous line by JavaScript’s automatic semicolon insertion. The leading ; prevents that.
How do I format JavaScript in VS Code?
Use Format Document (Shift+Alt+F, or Shift+Option+F on macOS). Install the Prettier extension and set it as the default formatter to match this page’s output exactly.