Formatting by Language

How to format JavaScript code on Mac

You can do this with Note My in one pass, with no toolchain to install. Here is what it changes in a .js file — indentation, brace style and collapsed statements — and what it leaves exactly as you wrote it.

A JavaScript file that has been through three editors, a diff tool and a paste from an AI chat tends to look like it. Two-space blocks beside four-space blocks. Braces in two styles. A fragment where a whole function sits on one line. You do not want to fix that by hand, or install a toolchain to do it.

Note My re-indents a JavaScript file in one pass, on your Mac, with no build step. This guide covers what that pass rewrites, where the controls are, and the four things worth doing before you press Apply.

Note

This all happens on your Mac. Nothing is uploaded, there is no account to create, and your source never leaves the machine.

What re-indent actually rewrites

The name undersells it. Re-indent does two jobs.

The first is obvious: every line lands at its correct depth for JavaScript, at the indent width and the tabs-or-spaces setting you have chosen. The second is structural — our indentation engine unpacks statements that share a line. A collapsed if (a) { doThing(); doOther(); } comes back as a properly opened block, one statement per line.

That second job is the one worth reaching for. A minified file, or one pasted back from somewhere that stripped its newlines, is not merely untidy — it is unreadable, and one pass makes it legible again.

What survives the pass matters as much. The text inside your strings and comments comes back exactly as you wrote it: a regular expression full of brackets, a URL with slashes, a template literal with braces in it.

Your code itself comes through untouched. Nothing is renamed and nothing is reordered — the pass changes where the characters sit, plus the two punctuation policies below, and leaves the meaning of the file exactly as you wrote it.

Open the Indentation sheet

Tip

One button drives the whole pass. The Indent button sits in the toolbar, in view whichever file you are working on, and opens the Indentation sheet where every setting below lives.

  1. Open the file and check the language

    Open your .js file with ⌘O, or drag it onto the tab bar. Our advanced language identifier sets the tab to JavaScript for you. If the tab is not JavaScript, click the Identify pill in the status bar to open the Language Inspector, which reads "Identified programming language: X" and lets you override it and confirm.

  2. Press the Indent button in the toolbar

    It is the braces glyph, towards the right of the bar. It does not act immediately — it opens the Indentation sheet, and nothing changes until you apply it.

  3. Set the language to JavaScript

    The picker holds sixteen entries: a global default plus fifteen languages. Choosing JavaScript snaps the brace style, width and tabs-or-spaces controls to your stored JavaScript values, and reveals the language-specific section underneath.

  4. Choose a brace style

    A pill switch offers Same line (K&R — the default) and Next line (Allman). Same line is the JavaScript convention and suits most projects; Next line is there for a codebase that has settled on Allman. Whichever you pick is applied consistently to every brace in the file.

  5. Set the width and the character

    Indent width defaults to 4; the sheet accepts 1 to 12. Tabs or spaces defaults to spaces. For two-space JavaScript, set the width to 2 here — it is stored per language, so it stays 2 next time.

  6. Set the JavaScript policies, then Apply

    Trailing commas and semicolons are covered below. Save the file first with ⌘S, so the version on disk is the one you want to come back to. Then, when the sheet reads the way you want, press Apply. Cancel, or ⎋, changes nothing.

Tip

Watch the preview card as you adjust the sheet. It renders a compact if <condition> { … } snippet in your chosen width, brace style and tab setting, so you can settle on a house style before a single line of your own file moves.

Trailing commas and semicolons

These are the two JavaScript-specific punctuation policies, and the ones most likely to change a file in a way a code review notices.

The JavaScript trailing comma and semicolon policies, with their options and defaults
PolicyOptionsDefault
Trailing commasNone · Multi-line · AllMulti-line
SemicolonsPreserve · Always · NeverPreserve

Trailing commas default to multi-line, the setting most JavaScript projects converge on: a literal split across several lines gets a comma after its last element, so adding a line later touches one line in the diff instead of two. None strips them. All adds them wherever the syntax permits, single-line literals included.

Semicolons default to preserve, which is deliberately conservative — your statement terminators are left exactly as found. Switch to always to terminate every statement, or never to drop them. If your team is split on this, preserve is the setting that never picks a side for you.

Object literals, JSX and wrap columns

Underneath the two policies sit the remaining JavaScript switches — object-literal splitting and JSX attribute wrapping — plus the column limits that govern when wrapping happens at all.

The column limits are worth setting deliberately. They arrive at 0, which leaves your own line breaks exactly where you put them — depth and structure are corrected, and a line you chose to keep long stays long. Give them a real column and the two switches beside them come into play: object-literal splitting decides how a long literal is opened out across several lines, and JSX attribute wrapping does the same for a tag carrying more props than fit comfortably. Set the column to the width your team reads at, turn on whichever switch matches the code you write most, and a sprawling configuration object or a crowded component tag comes back in a shape you can take in at a glance.

Important

Three settings are remembered per language: brace style, indent width, and tabs-or-spaces. Every other control — including the trailing-comma and semicolon policies — is remembered once and shared by every language, so the sheet's "Reset to global" link leaves those alone.

Recovering comments that swallowed code

The sheet has a checkbox marked Recover damaged comments, off by default. It is for one specific kind of damage: a line where a comment marker has absorbed real code, so // Preserve state let x = 1 let y = 2 sits in your file as one commented line with two live statements trapped inside it. Bad merges, stripped newlines and copies out of a terminal all do this.

Turn it on and that line comes back as a comment on its own, with the statements that were stuck behind it restored underneath as live code at the depth they belong to.

It is deliberately cautious. It works on single-line comments only. Documentation markers — ///, //!, /** and /*! — are never touched, and block comments are tidied inside their markers rather than un-commented, so code you deliberately commented out stays commented out.

It is at home in a .js file, and equally in the TypeScript, Swift, Go, Rust and Python files you are likely to have open in the tabs beside it. Leave it off for everyday passes and reach for it on the one file that has been mangled: the checkbox is remembered, so you can turn it on for the repair and switch it back off once the file reads properly again.

Four things worth doing before you apply

None of this takes long, and together they turn one pass into a habit you can trust on any file.

  • Bring the big files. A minified bundle or a thousand-line module is exactly the sort of thing to hand over — our large-file engine is built for that weight. On an ordinary source file the reformatted text arrives at once; on a file of real size the window works for a moment and then the whole document appears in its new shape, every line landing together rather than a screen at a time.
  • Balance your braces first. A file that closes every brace it opens comes back perfectly stepped, top to bottom. If the stepping changes character from one point downwards, read that as a signal worth having: an unclosed { is sitting just above it. Close it, apply again, and the rest of the file falls into line behind it.
  • Think in whole files. Apply reformats the document in front of you in one pass, which is where re-indent earns its keep — the entire file lands in a single style at once, rather than a block at a time.
  • Save first, every time. ⌘S before you press Apply puts a copy of the file on disk that is yours to return to whenever you want it.

Which is why the procedure above saves first. With the file on disk, File ▸ Reload from Disk (⌘R) throws away the reformatted text on screen and brings back the version you saved — the dependable escape hatch from a result you did not want.

Troubleshooting

The Indent button did nothing

Two harmless cases. An empty document has nothing to indent. And if your file already matches the settings in the sheet, there is nothing to change, so nothing appears to happen. Check a nested block against your indent width to confirm.

The tab says Plain Text rather than JavaScript

A saved .js file arrives as JavaScript the moment you open it — our advanced language identifier takes care of that for you, so the JavaScript rules are there to use. A loose fragment pasted into an untitled tab can land as Plain Text instead. When it does, set the language yourself from the status-bar Identify pill, or in the sheet's picker; the JavaScript section then becomes available and the JavaScript rules apply. Saving the tab as a .js file is the permanent fix.

Typing JSX in a .js file

The six auto-pairs are all working for you here: (), [], {}, "", '' and backticks each close themselves as you type, which covers the props, arrays and template literals that make up most of a component. Type the closing tag yourself, and Smart Edit keeps each new line at the depth you are working at. When a component has drifted out of shape anyway, the Indent button puts the whole file back in order in one pass.

The file is full of smart quotes after a paste

That is a cleanup job, and there is a tool aimed squarely at it. Clean ▸ Clean Invisible / Special Characters… opens a review sheet, where Smart quotes, Smart dashes and Ellipsis are among the categories our cleanup rules can fix. The default Code-safe preset is the one to start with, and you see what will change before you apply it.

Two-space and four-space blocks came back mixed

Check that the sheet's language was JavaScript and not the global default when you applied it. Width is one of the three values remembered per language, so a width you set against the global default does not govern a file the app is treating as JavaScript. Choose JavaScript in the picker, set the width to 2, and apply again.

package.json needs formatting too

Different command. Use Edit ▸ Format JSON, which re-indents with two spaces — but note it also sorts the keys, which for a manifest is a real change. Edit ▸ Validate JSON checks the file and reports problems without changing anything, and its errors carry (around line N, column M).

Where one pass fits into a working day

Three moments come round again and again, and the same button covers all of them.

Straight after a paste. Code that arrives from an AI answer, a terminal window or a colleague's message lands in whatever shape the journey left it — two-space blocks, a function collapsed onto one line, braces in a style that is not yours. Open a tab, paste, press Indent, apply. One pass and it reads like the rest of your project. Paste always arrives as plain text, so nothing brings a font or a background colour in with it.

Before a review. Set the brace style, width, trailing-comma and semicolon policies to match your team once, and every file you touch afterwards goes into the diff in the house style. Because brace style, indent width and tabs-or-spaces are remembered per language, a JavaScript file and a TypeScript file each keep their own conventions with no switching back and forth in between.

At the start of something new. Our template library includes a main.js starter, so a fresh file can open with a shape already in place, ready to take the same settings as everything else in the project.

Between those moments, re-indent stays out of the way. It runs when you press Apply and at no other time, so nothing is rearranged while you are mid-thought. Smart Edit handles the small courtesies as you write — indenting each new line, closing your pairs — and it carries its own switches, so you decide how much of that help you want.

Frequently asked questions

How do I start a format pass?

From the toolbar. The Indent button — the braces glyph, towards the right of the bar — opens the Indentation sheet wherever you are in a file. Once the sheet is up, the keyboard takes over: Return applies, Escape cancels.

Will formatting change my strings or comments?

Your strings and comments come back exactly as you wrote them. Our indentation engine changes where your code sits on the line, and leaves the text you put inside a string or a comment word for word — a regular expression full of brackets, a URL, a licence header, a template literal with braces in it. The one control that restructures a comment is the Recover damaged comments checkbox, and it stays off until you turn it on.

Can I make it stop adding trailing commas?

Yes. Set the trailing-comma policy to None in the sheet's JavaScript section. The default is Multi-line, which adds them only to literals already split across lines.

Does it work on TypeScript as well?

Yes. Select TypeScript in the sheet's language picker rather than JavaScript. Its brace style, width and tabs-or-spaces setting are remembered separately, so you can keep two house styles side by side.

Which document does the sheet act on?

The one in front of you. The sheet applies to the active document, so each file gets the style you have chosen for its language: switch tab, press Indent, apply again. Your settings are already waiting, so a second file takes seconds. Searching across a folder stays read-only by design, so nothing is ever rewritten out of sight.

Does this work offline?

Completely. Formatting, language identification and colouring all happen on your Mac. Nothing is uploaded and your files never leave the machine, so a plane, a train or a locked-down office network makes no difference to the result. It requires macOS 13.0 or later.