How to Format JavaScript Code: Best Practices and Tools

End the tabs-vs-spaces debate forever (well, almost)

โœจ ๐Ÿงน ๐Ÿ“ ๐Ÿ’…

TL;DR: Install Prettier, configure it once, set up format-on-save and a pre-commit hook. Done. Never argue about semicolons, tabs, or trailing commas again. Your team will ship faster, review code faster, and save their energy for decisions that actually matter.

Code formatting seems trivial until you join a team where one person uses tabs, another uses 4 spaces, a third writes everything on one line, and someone has opinions about where the opening brace goes. Suddenly your pull request has 500 changed lines and exactly 3 of them are actual logic changes.

Let's fix that.

๐ŸŽจ Messy code vs formatted code: same logic, wildly different vibes

Why Does Formatting Even Matter?

It's not about aesthetics โ€” consistent formatting has real, measurable effects:

The Great Formatting Debates (And How to End Them)

Tabs vs Spaces

The JavaScript ecosystem has overwhelmingly settled on 2 spaces. React, Vue, Angular, Node.js โ€” they all use it. Some teams prefer 4 spaces (especially those coming from Python). Tabs have the advantage of configurable width per developer, but they're less common in JS land.

๐Ÿ˜„

Dev Joke: A developer who uses spaces makes more money than one who uses tabs. At least, that's what the Stack Overflow survey said. (Correlation, not causation โ€” please don't switch to spaces expecting a raise.)

Semicolons: Always vs Never

JavaScript has Automatic Semicolon Insertion (ASI), meaning semicolons are technically optional. But ASI has some nasty gotchas:

// This looks like it returns an object, but returns undefined!
function getData() {
  return
  {
    name: 'Alice'
  }
}
// ASI inserts a semicolon after "return", so the object
// is unreachable dead code. Surprise! ๐ŸŽ‰

Most style guides recommend always using semicolons. The real answer? Pick one and let Prettier enforce it.

Trailing Commas: Yes, Please

This one's actually easy โ€” trailing commas produce cleaner git diffs:

// Without trailing comma โ€” adding "cherry" changes TWO lines
const fruits = [
  'apple',
- 'banana'
+ 'banana',
+ 'cherry'
];

// With trailing comma โ€” adding "cherry" changes ONE line
const fruits = [
  'apple',
  'banana',
+ 'cherry',
];

Prettier: The "I Don't Care, Just Make It Pretty" Tool

Prettier is an opinionated code formatter. It takes your code and reformats it according to its rules. You get almost no say in the matter โ€” and that's the whole point. No more debates.

# Install
npm install --save-dev prettier

# Format a file
npx prettier --write src/app.js

# Format everything
npx prettier --write "src/**/*.{js,jsx,ts,tsx,css,json}"

Configure it with a .prettierrc:

{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 80,
  "bracketSpacing": true,
  "arrowParens": "always"
}
๐Ÿค– Prettier: "You don't get an opinion. Your code is pretty now."

ESLint + Prettier: The Dream Team

ESLint catches bugs and enforces patterns (logic rules). Prettier handles formatting (style rules). Use them together:

# Install the integration
npm install --save-dev eslint eslint-config-prettier

# eslint.config.js
import prettier from 'eslint-config-prettier';

export default [
  {
    rules: {
      'no-unused-vars': 'warn',
      'no-console': 'warn',
      'prefer-const': 'error',
    },
  },
  prettier, // Turns off ESLint rules that conflict with Prettier
];

Set Up Format-on-Save (Do This Now)

VS Code

Add this to .vscode/settings.json and commit it so your whole team gets it:

{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}

Pre-Commit Hook (The Safety Net)

Even with format-on-save, someone will eventually commit from the terminal or use a different editor. Catch unformatted code at the gate:

# Install
npm install --save-dev husky lint-staged

# package.json
{
  "lint-staged": {
    "*.{js,jsx,ts,tsx,css,json,md}": "prettier --write"
  }
}

# Set up Husky
npx husky init
echo "npx lint-staged" > .husky/pre-commit
๐Ÿ’ก

Pro Tip: This workflow means formatting is always correct in your repo, regardless of what editor each developer uses. It's like having a bouncer who checks everyone's dress code at the door.

Before & After: See the Difference

// BEFORE: the "I was in a hurry" style
const fetchData=async(url,options)=>{
const response=await fetch(url,{method:'GET',headers:{'Content-Type':'application/json',...options?.headers},
...options})
if(!response.ok){throw new Error(`HTTP ${response.status}: ${response.statusText}`)}
const data=await response.json()
return data}

// AFTER: Prettier-formatted (same logic, readable by humans)
const fetchData = async (url, options) => {
  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      ...options?.headers,
    },
    ...options,
  });
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }
  const data = await response.json();
  return data;
};

Same exact code. One version makes your eyes bleed; the other you can actually review at 4 PM on a Friday.

โš ๏ธ

One More Thing: Add an .editorconfig file to your project for cross-editor basics (indent style, line endings, charset). It's the universal translator for editors that don't know about Prettier.

๐Ÿ Format-on-save + pre-commit hook = formatting solved forever

Wrapping Up

Stop debating formatting in code reviews. Install Prettier, configure it once, set up format-on-save and a pre-commit hook, and never think about it again. Your team will write code faster, review code faster, and spend their energy on the decisions that actually matter โ€” like what to name variables. (That's a whole other article.)

Try It Yourself

Need to quickly format a snippet of JavaScript, HTML, or CSS? Paste it into our online code beautifier for instant formatting.

Open Code Beautifier →