JavaScript and JSX Formatter

Format JavaScript the way Prettier would in your editor, read minified bundles, or shrink a script for production.

Input

Settings

History

Load from URL

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 writes order => order.total when 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.

Input
!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);
Output
!(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);
Open this example in the tool

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.

Input
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;
Output
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
Open this example in the tool

React component with JSX

JSX is laid out like HTML, and single-parameter arrow functions such as item => … lose their parentheses.

Input
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>}
Output
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>
  );
}
Open this example in the tool

Utility module minified with Terser

The ES module is compressed and its local variables are mangled, while the exported names stay intact.

Input
/**
 * 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);
}
Output
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)}
Open this example in the tool

Common errors and how to fix them

ErrorCauseFix
Unexpected token
Explained
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 firstTerser 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.

Related tools