How the JavaScript Formatter works

The formatter first splits your code into tokens. Its tokenizer knows the parts of JavaScript where spaces and symbols must not be touched: single- and double-quoted strings, template literals (including nested ${...} expressions), line and block comments, and regular expression literals. Whether a / starts a regular expression or means division is decided from the token before it, the same way a JavaScript engine decides.

It then prints the tokens again: a line break after {, after each statement's ; (but not inside the head of a for loop) and around }, indentation by nesting depth, spaces around operators and after commas and keywords, and case labels indented inside switch. Short object literals written on one line, such as { id: o.id }, stay on one line.

The output is equivalent to the input. The text of every string, template, regular expression and comment is copied unchanged, and every line break that was already in your code is kept. That matters because JavaScript inserts semicolons automatically at some line breaks (for example after return), so removing one could change what the code does. The formatter does not rename variables or reorder anything, and it does not check that the code is valid beyond the tokens.

How to use the JavaScript Formatter

  1. Paste your JavaScript into the input box, open a .js file, or select Load example.
  2. Choose the indentation: 2 spaces, 4 spaces or tabs.
  3. Select Format JavaScript, or press Ctrl + Enter (Cmd + Enter on a Mac).
  4. Copy the formatted code or download it as a .js file. If a string, comment or template literal is not closed, the error shows its line and column.

Example

This minified code:

function total(items){let sum=0;for(const i of items){if(i.qty>0)sum+=i.price*i.qty}return sum/100}

is formatted with 2-space indentation as:

function total(items) {
  let sum = 0;
  for (const i of items) {
    if (i.qty > 0) sum += i.price * i.qty
  }
  return sum / 100
}

If a string is not closed, for example const name = "Keyboard; on line 2, the tool reports Invalid JavaScript at line 2, column 14: Unterminated string literal (strings cannot span lines).

Common use cases

  • Reading minified code from a website or a bundled library while debugging.
  • Tidying a script pasted from a chat message, a log or an answer online.
  • Re-indenting old code with mixed tabs and spaces before refactoring it.
  • Making a one-line bookmarklet or inline event handler readable.

Common errors and how to fix them

Invalid JavaScript at line N
The code is parsed before it is printed, so genuine syntax errors stop the process. Fix the reported line, and bear in mind that JSX and TypeScript are not plain JavaScript.
Unterminated string literal (strings cannot span lines)
A quoted string was opened and a real newline followed before the closing quote. Use a template literal in backticks for multi-line text, or escape the break as \n.
Unterminated template literal. Add the closing backtick
A backtick string is still open, usually because an interpolation was opened with ${ and never closed with }. Check the interpolations in the reported region.
The output is not smaller
This is a formatter, not a minifier. It makes minified code readable rather than compact, and it renames nothing, so behaviour is unchanged.

Frequently asked questions

Can formatting break my code?

The formatter only changes whitespace. It never changes the text of strings, template literals, regular expressions or comments, it keeps every line break that was in your code so automatic semicolon insertion works the same (for example after return), and it keeps a space wherever removing one would join two tokens, such as a + +b.

How does it tell a regular expression from division?

It looks at the previous token, like a JavaScript engine does. After a value such as a variable, a number or a closing parenthesis, / is division; after an operator, a keyword such as return, or an opening bracket, / starts a regular expression. The parentheses after if, for and while are recognised, so if (x) /re/.test(s) is read correctly.

Does it support modern JavaScript?

Yes. Arrow functions, classes and private #fields, async and await, optional chaining (?.), nullish coalescing (??), template literals with nested expressions, BigInt and numeric separators, and import and export statements are all tokenized correctly. JSX and TypeScript type annotations are not specifically supported.

Does it rename variables or undo minification completely?

No. It restores layout only. Short variable names chosen by a minifier stay as they are, because the original names are not stored in minified code.

Is my code uploaded to your server?

No. Formatting runs in your browser, and your code is not sent to our server.