JavaScript Code Formatting: Tools and Standards
Open any pull request where half the diff is whitespace changes and you will feel the pain immediately. Formatting inconsistencies waste time, clutter code reviews, and create merge conflicts that have nothing to do with logic. The fix is straightforward: pick a formatting standard, automate enforcement, and never think about it again.
This guide walks through the tools and standards that make JavaScript formatting a solved problem.
Why Consistent Formatting Matters
Formatting is not about aesthetics β it is about team velocity. When every developer uses different indentation, bracket placement, and line lengths, three things happen:
Code reviews slow down. Reviewers spend mental energy parsing unfamiliar formatting instead of evaluating logic. A function that looks different from everything else in the codebase draws attention for the wrong reasons.
Merge conflicts multiply. Developer A reformats a file with tabs, Developer B uses spaces, and now Git shows every line as changed. The actual three-line bug fix gets buried.
Cognitive load increases. Switching between files with different styles forces your brain to re-parse structure constantly. Consistent formatting lets you read code like prose β your eyes know where to look.
The solution is not arguing about which style is best. It is picking one and automating it.
Popular JavaScript Style Guides
Before choosing tools, it helps to understand the major style guides that shaped JavaScript formatting conventions.
Airbnb Style Guide
The most widely adopted JavaScript style guide. It enforces semicolons, prefers single quotes, requires trailing commas in multiline constructs, and uses 2-space indentation. The eslint config (eslint-config-airbnb) bundles hundreds of rules covering both formatting and code quality.
// Airbnb style
const getUserData = (userId) => {
const user = findUser(userId);
return {
name: user.name,
email: user.email,
};
};
Standard Style
Takes the opposite approach on semicolons β no semicolons, ever. Uses 2-space indentation and single quotes. The standard package includes its own linter, so you do not need a separate ESLint config.
// Standard style
const getUserData = (userId) => {
const user = findUser(userId)
return {
name: user.name,
email: user.email
}
}
Google Style Guide
Similar to Airbnb but with some differences in JSDoc requirements and naming conventions. Uses 2-space indentation, requires semicolons, and prefers single quotes.
Each of these style guides has trade-offs. The important thing is consistency, not which one you pick. And increasingly, teams skip the debate entirely by letting Prettier decide.
Prettier: The Opinionated Formatter
Prettier changed JavaScript formatting by removing most of the decisions. It parses your code into an AST (Abstract Syntax Tree) and reprints it according to its own rules. You do not configure individual formatting choices β you set a few high-level options and Prettier handles the rest.
Installation
npm install --save-dev prettier
Create a .prettierrc configuration file:
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"bracketSpacing": true,
"arrowParens": "always"
}
Key Configuration Options
printWidth (default: 80) β The line length where Prettier wraps code. This is not a hard limit β Prettier uses it as a guideline for when to break expressions into multiple lines. Setting it to 100 or 120 is common for teams with wide monitors.
semi (default: true) β Whether to add semicolons at the end of statements. Set to false if you prefer the Standard style.
singleQuote (default: false) β Use single quotes instead of double quotes. Most JavaScript developers prefer single quotes, making true the more common setting.
trailingComma (default: "all") β Adds trailing commas wherever valid. This produces cleaner Git diffs because adding a new item to a list only shows one changed line instead of two.
// Without trailing commas β adding "d" changes two lines
const items = [
- "a",
- "b",
- "c"
+ "a",
+ "b",
+ "c",
+ "d"
];
// With trailing commas β adding "d" changes one line
const items = [
"a",
"b",
"c",
+ "d",
];
arrowParens (default: "always") β Whether to wrap a single arrow function parameter in parentheses. "always" means (x) => x, "avoid" means x => x.
Running Prettier
# Format all files
npx prettier --write .
# Check without modifying
npx prettier --check .
# Format specific file types
npx prettier --write "src/**/*.{js,jsx,ts,tsx}"
Add a .prettierignore file to skip generated files:
node_modules
dist
build
coverage
*.min.js
If you work with minified JavaScript, our Code Minifier handles minification properly β never hand-edit minified code.
ESLint: Beyond Formatting
ESLint serves a different purpose than Prettier. While Prettier handles how code looks, ESLint catches how code behaves. ESLint rules fall into two categories:
Formatting rules β indentation, spacing, bracket placement. These overlap with Prettier and should generally be disabled when using both tools.
Code quality rules β unused variables, unreachable code, implicit type coercion, missing error handling. These are where ESLint shines.
Recommended Setup
npm install --save-dev eslint @eslint/js
A minimal eslint.config.js:
import js from '@eslint/js';
export default [
js.configs.recommended,
{
rules: {
'no-unused-vars': 'warn',
'no-console': 'warn',
'eqeqeq': 'error',
'no-implicit-coercion': 'error',
},
},
];
For TypeScript projects, add typescript-eslint:
npm install --save-dev typescript-eslint
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
export default tseslint.config(
js.configs.recommended,
...tseslint.configs.recommended,
);
Prettier + ESLint Integration
Running both tools without coordination creates conflicts β ESLint formatting rules fight Prettier's output. The solution is eslint-config-prettier, which disables all ESLint rules that conflict with Prettier.
npm install --save-dev eslint-config-prettier
import js from '@eslint/js';
import prettierConfig from 'eslint-config-prettier';
export default [
js.configs.recommended,
prettierConfig,
{
rules: {
// Only code quality rules here
'no-unused-vars': 'warn',
'eqeqeq': 'error',
},
},
];
With this setup, Prettier owns formatting and ESLint owns code quality. No conflicts, no confusion.
EditorConfig for Cross-Editor Consistency
Not everyone on your team uses the same editor. EditorConfig provides a baseline that works across VS Code, WebStorm, Vim, Sublime Text, and most other editors.
Create an .editorconfig file in your project root:
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
EditorConfig handles the basics β indentation, line endings, trailing whitespace β before Prettier even runs. This prevents the common issue where a Windows developer introduces \r\n line endings into a Unix-based project.
Git Hooks with Husky and lint-staged
Automated formatting only works if it actually runs. Relying on developers to remember npx prettier --write before every commit does not scale. Git hooks solve this.
Setup
npm install --save-dev husky lint-staged
npx husky init
Add to package.json:
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"prettier --write",
"eslint --fix"
],
"*.{json,md,css}": [
"prettier --write"
]
}
}
Update the Husky pre-commit hook (.husky/pre-commit):
npx lint-staged
Now every commit automatically formats staged files and runs ESLint fixes. Developers never need to think about formatting β it just happens.
This is the gold standard for team projects: Prettier formats, ESLint catches bugs, Husky enforces both on every commit.
The Semicolons Debate
No JavaScript formatting discussion is complete without the semicolons question. Here is the practical answer: it does not matter, as long as your team is consistent.
Pro-semicolons: Explicit statement termination avoids ASI (Automatic Semicolon Insertion) edge cases. The Airbnb and Google style guides require them.
No-semicolons: JavaScript's ASI handles termination automatically. The code is cleaner with less visual noise. The Standard style guide omits them.
The ASI gotchas that people warn about β like lines starting with ( or [ β are caught by ESLint's no-unexpected-multiline rule. In practice, going semicolon-free with proper linting is perfectly safe.
Pick one, configure Prettier's semi option, and move on. Prettier will add or remove them consistently either way.
Tabs vs Spaces in JavaScript
The JavaScript ecosystem overwhelmingly uses spaces β specifically, 2-space indentation. This is not universal (Go uses tabs, Python uses 4 spaces), but in JavaScript it is the strong convention.
Why 2 spaces? JavaScript's nested callback patterns and chained methods create deep indentation quickly. Two spaces keep deeply nested code readable without pushing it off the right edge of the screen.
Why not tabs? Tabs allow each developer to set their own display width, which sounds good but means code alignment breaks across editors. With spaces, what you see is what everyone sees.
Configure this once in Prettier (tabWidth: 2, useTabs: false) and EditorConfig (indent_style = space, indent_size = 2), and it is settled.
Common Formatting Pitfalls
Inconsistent Arrow Functions
// Inconsistent β avoid this
const double = x => x * 2;
const add = (a, b) => a + b;
const greet = (name) => {
return `Hello, ${name}`;
};
// Consistent β Prettier with arrowParens: "always"
const double = (x) => x * 2;
const add = (a, b) => a + b;
const greet = (name) => {
return `Hello, ${name}`;
};
Object Destructuring Style
// Cramped β hard to read
const {name,email,role} = user;
// Formatted β Prettier handles this automatically
const { name, email, role } = user;
// Multiline for many properties
const {
name,
email,
role,
department,
startDate,
} = user;
Import Statement Organization
Prettier does not sort imports β that is a code quality concern, not formatting. Use eslint-plugin-import or the simple-import-sort plugin:
// Organized imports
import React from 'react';
import { useState, useEffect } from 'react';
import { Button } from '@/components/Button';
import { Modal } from '@/components/Modal';
import { formatDate } from '../utils/dates';
import { validateEmail } from '../utils/validation';
Long Ternary Expressions
// Unreadable single line
const label = isAdmin ? 'Admin Dashboard' : hasEditPermission ? 'Editor View' : 'Read Only';
// Prettier reformats to readable multiline
const label = isAdmin
? 'Admin Dashboard'
: hasEditPermission
? 'Editor View'
: 'Read Only';
Setting Up a New Project
Here is a complete setup checklist for a new JavaScript or TypeScript project:
-
Install dependencies:
npm install --save-dev prettier eslint eslint-config-prettier husky lint-staged -
Create
.prettierrcwith your team's preferences -
Create
.editorconfigfor cross-editor baseline -
Configure ESLint with code-quality rules only (no formatting rules)
-
Set up Husky + lint-staged for pre-commit enforcement
-
Add npm scripts:
{ "scripts": { "format": "prettier --write .", "format:check": "prettier --check .", "lint": "eslint .", "lint:fix": "eslint --fix ." } } -
Run initial formatting on the entire codebase:
npm run format -
Commit the formatted code as a single commit so it is easy to skip in
git blamewith--ignore-rev
Formatting in Practice
Once your formatting pipeline is set up, the day-to-day experience changes dramatically:
- Write code however you want. Prettier reformats on save or commit.
- Pull requests show only logic changes. No more whitespace noise.
- New team members are productive immediately. The tooling enforces standards without a style guide document.
- Arguments about style disappear. Prettier is the authority, not any individual developer.
When you need to check the structure of JSON data you are working with, our JSON Formatter makes inspection easy β paste any JSON and get instant, readable formatting right in your browser.
Related Resources
For more on code formatting and developer tooling:
- Code Minification Guide β Learn when and how to minify JavaScript for production
- Naming Conventions in Programming β Consistent naming is the other half of readable code
- SQL Formatting Best Practices β Apply the same formatting discipline to your database queries
Consistent formatting is one of those rare engineering investments that pays off immediately and keeps paying off. Set it up once, automate it, and spend your energy on the code that actually matters.