All articles
Formatters
8 min readBy DevUtilX Team

JavaScript Code Formatting: Prettier, ESLint and Style Guides

Learn how Prettier and ESLint split formatting and linting, which JavaScript style guides matter, and how to automate consistent code style.

JavaScript Code Formatting: Prettier, ESLint and Style Guides

Few arguments waste as much engineering time as the one about tabs, spaces and semicolons. Every team has had it, and almost every team eventually learns the same lesson: stop debating style by hand and let tools enforce it. This guide explains why consistent JavaScript formatting matters, how Prettier and ESLint divide the work, which style guides are worth knowing, and how to set everything up so formatting stops being a topic in code review.

What is code formatting, and why does it matter?

Code formatting is the layout of source code: indentation, line breaks, quote style, spacing around operators and the placement of braces. JavaScript is especially tolerant here. The engine ignores nearly all whitespace, so these two snippets behave identically:

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

The machine does not care, but people do. Formatting pays off in four concrete ways.

Readability. Indentation shows structure. A reader can see where a block starts and ends without counting braces.

Smaller diffs. When everyone formats the same way, a pull request shows only real changes. Without a shared format, a one-line fix can arrive buried in hundreds of whitespace edits that hide the actual logic change.

Fewer review arguments. Style comments such as "add a space here" or "wrap this line" are noise. Automating them frees reviewers to discuss design, naming and bugs.

Easier onboarding. New contributors do not need to memorise a style document. They save the file and the tool does the rest.

Formatters versus linters

People often mix up two different kinds of tools. Understanding the difference is the key to a clean setup.

A formatter rewrites your code's layout. It parses the source into a syntax tree and prints it back using fixed rules. It never changes what the program does. Prettier is the best-known example.

A linter analyses your code for likely bugs and bad practices: unused variables, unreachable code, a missing await, or comparing with == where === was intended. ESLint is the standard linter for JavaScript and TypeScript.

The two overlap on style, which is where trouble used to start. ESLint once shipped many formatting rules (quotes, semicolons, indentation), and these fought with Prettier's output. The modern recommendation is simple: let the formatter own layout, and let the linter own correctness. Turn off any ESLint rule that only concerns style, or use a config such as eslint-config-prettier that does it for you. The Prettier documentation describes this split in its page on integrating with linters.

How Prettier works

Prettier is "opinionated" on purpose. Its rationale document explains the thinking: it offers very few options, because every option is another thing to argue about. The core idea is that Prettier throws away your original formatting and reprints the whole program from the syntax tree, wrapping lines to fit a target width.

A few behaviours are worth knowing:

  • Line width. The default print width is 80 characters. Prettier fits as much as possible on one line, and breaks only when it must.
  • Preserved decisions. Prettier keeps blank lines you added between statements (collapsing multiples into one), and it keeps an object on multiple lines if you put a newline between the opening brace and the first key.
  • Semicolons and quotes. It adds semicolons by default and prefers double quotes, but both are configurable.
  • Trailing commas. Modern defaults add trailing commas in multi-line structures, which produces cleaner diffs when you append items.

A minimal configuration lives in a .prettierrc file:

{
  "semi": true,
  "singleQuote": true,
  "trailingComma": "all",
  "printWidth": 100,
  "tabWidth": 2
}

The full list is short; see the official options reference. Resist the urge to tune every setting. The point of a formatter is agreement, not perfection.

How ESLint fits in

ESLint reads your code, applies a set of rules, and reports problems. Each rule can be set to "off", "warn" or "error", and many have automatic fixes. The current configuration format is the "flat config" file, eslint.config.js, described in the ESLint configuration docs. A small example:

import js from "@eslint/js";
import prettier from "eslint-config-prettier";

export default [
  js.configs.recommended,
  prettier, // disables rules that conflict with Prettier
  {
    rules: {
      "no-unused-vars": "warn",
      eqeqeq: "error",
      "prefer-const": "error",
    },
  },
];

The rules above catch real defects rather than style: eqeqeq prevents surprising type coercion, prefer-const signals variables that never change, and no-unused-vars highlights dead code. The getting started guide walks through installation.

If you would rather adopt a convention than invent one, several well-known guides exist:

  • Airbnb JavaScript Style Guide. One of the most widely used, with detailed rules and rationale. It is published on GitHub and has a matching ESLint config.
  • Google JavaScript Style Guide. A thorough document covering formatting, naming and language features, available at google.github.io/styleguide.
  • StandardJS. A zero-configuration style that famously omits semicolons. See standardjs.com.

The semicolon debate deserves a note. JavaScript has a feature called automatic semicolon insertion, where the parser inserts semicolons at certain line endings. It works most of the time, but a few edge cases (a line starting with ( or [, or a return followed by a newline) can change meaning silently. Whichever side you pick, a formatter removes the risk because it applies your choice consistently.

Another long-running argument is indentation placement. The indentation style article lists the historical variants (K&R, Allman and others). In JavaScript the overwhelming norm is the K&R-style "braces on the same line" layout, and tools default to it.

Real-world use cases

Cleaning up minified or inherited code. You open a bundled file, a pasted snippet from a chat, or a legacy script written in 2012. It is one long line or has inconsistent indentation. Beautifying it is the first step to understanding it. A quick online formatter is ideal here because you do not need a whole project setup.

Reviewing API or SDK snippets. Code in documentation and forums is often unformatted. Reformatting it before pasting into your project keeps the diff clean.

Enforcing a team standard. In a repository, run the formatter on save in the editor and again in a pre-commit hook, so unformatted code never reaches the main branch.

Teaching and writing. For blog posts, slides and documentation, consistently formatted code is far easier to read and copy.

Common mistakes

  • Running the formatter and linter against each other. If ESLint style rules conflict with Prettier, you get a loop where each tool undoes the other. Disable the overlap.
  • Formatting only some files. A half-formatted repository creates noisy diffs every time someone touches an old file. Format everything once, in a single dedicated commit.
  • Bikeshedding config. Spending a meeting on printWidth is exactly the waste the tool was meant to prevent.
  • Forgetting generated files. Add build output, vendor code and lockfiles to .prettierignore so they are left alone.

Step-by-step: format JavaScript with DevUtilX

When you just need to clean a snippet quickly, without installing anything, the DevUtilX JavaScript/TypeScript Beautifier does the job in your browser.

  1. Open the beautifier tool.
  2. Paste your JavaScript or TypeScript into the input editor.
  3. Choose the indentation you prefer (2 spaces, 4 spaces or tabs).
  4. Run the formatter and review the output in the result pane.
  5. Copy the cleaned code back into your project.

Because the work happens in the browser, your code is not uploaded anywhere, which matters when the snippet contains internal logic. If your goal is the opposite, shrinking code for production, pair this with the JavaScript minifier.

Setting up a project for automatic formatting

For a real project, make formatting automatic rather than manual. A reliable setup has four layers.

1. Install and configure. Add Prettier and ESLint as dev dependencies and commit the config files, so everyone shares the same rules.

npm install --save-dev prettier eslint eslint-config-prettier

2. Add scripts. Give the team obvious commands:

{
  "scripts": {
    "format": "prettier --write .",
    "format:check": "prettier --check .",
    "lint": "eslint ."
  }
}

3. Share editor settings. An EditorConfig file sets basic rules such as indent style and final newline for almost every editor, including people who do not use your formatter plugin.

root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true

4. Enforce in CI and on commit. Run format:check and lint in your continuous integration pipeline so a failing check blocks unformatted code. Optionally add a pre-commit hook with a tool like lint-staged so only changed files are processed locally.

Best practices

  • Pick a standard and stop. The best style is the one everyone follows. Prefer Prettier defaults unless you have a strong reason.
  • Separate concerns. Formatter for layout, linter for bugs. Never let the two own the same rule.
  • Format on save. The faster the feedback, the less friction developers feel.
  • Do one big formatting commit. When adopting a formatter on an existing codebase, apply it in a single commit and record that commit's hash in a .git-blame-ignore-revs file so git blame stays useful.
  • Keep code readable beyond layout. A formatter cannot fix unclear names, giant functions or missing comments. Use the time saved on style to improve those.
  • Version your tools. Pin the formatter version. Different versions can print code slightly differently, which creates diff noise between teammates.

Comparison and alternatives

Prettier is not the only choice, and it is worth knowing what else exists.

  • Prettier: the dominant opinionated formatter, supporting JavaScript, TypeScript, CSS, HTML, JSON and Markdown. See the Prettier repository for its roadmap and issues.
  • Biome: a fast, Rust-based tool that combines formatting and linting in one binary, and aims for Prettier-compatible output.
  • dprint: another Rust-based formatter focused on speed and configurability.
  • ESLint with stylistic plugins: possible, but you re-take responsibility for style rules the community has largely moved away from.
  • Editor built-ins: convenient for solo work, but they differ between editors, which is why a project-level tool is preferable for teams.

The honest summary is that all of these produce readable code. What matters is that the whole team uses the same one and that it runs automatically.

FAQ

Should I use tabs or spaces?
Either works. Spaces give identical rendering everywhere, while tabs let each reader choose their own visual width and are friendlier for accessibility. Pick one in your config and let the formatter enforce it.

Do I need semicolons in JavaScript?
Not strictly, because of automatic semicolon insertion, but a few edge cases can bite. Using semicolons consistently, enforced by a formatter, is the lower-risk option.

What is the difference between Prettier and ESLint?
Prettier formats layout and never changes behaviour. ESLint analyses code for bugs and bad practices and can also enforce conventions. Use both, with Prettier in charge of style.

Does formatting change how my code runs?
No. A formatter only changes whitespace and punctuation that the language treats as equivalent. If behaviour changes, that is a bug in the tool, so report it.

Can I format TypeScript and JSX the same way?
Yes. Prettier and ESLint both support TypeScript and JSX, and the DevUtilX beautifier handles JavaScript and TypeScript.

Is it safe to paste proprietary code into an online formatter?
Only if the tool runs locally. Browser-based tools that process everything client-side, like DevUtilX, never send your code to a server. Always check a tool's privacy statement first.

Conclusion

Consistent formatting is one of the cheapest quality improvements a JavaScript team can make. Let a formatter such as Prettier own the layout, let ESLint catch real mistakes, share a small set of config files, and enforce both on save and in CI. For quick one-off cleanups, the JavaScript/TypeScript Beautifier gives you tidy code in seconds. To continue, read our JSON Formatting Guide for the same ideas applied to data, and explore the JavaScript minifier when you are ready to ship.

Further reading

Try the tools

Further reading

Related articles