DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

SBOMs are essential to circumventing software supply chain attacks, and they provide visibility into various software components.

Related

  • Static Analysis with ESLint and LWC
  • Why Tailwind CSS Can Be Used Instead of Bootstrap CSS
  • Maximizing Productivity: GitHub Copilot With Custom Instructions in VS Code
  • Exploring Intercooler.js: Simplify AJAX With HTML Attributes

Trending

  • Micro Frontends to Microservices: Orchestrating a Truly End-to-End Architecture
  • The Cybersecurity Blind Spot in DevOps Pipelines
  • The Battle of the Frameworks: Choosing the Right Tech Stack
  • Advanced gRPC in Microservices: Hard-Won Insights and Best Practices
  1. DZone
  2. Coding
  3. Languages
  4. The Ultimate Guide to Code Formatting: Prettier vs ESLint vs Biome

The Ultimate Guide to Code Formatting: Prettier vs ESLint vs Biome

Break down the differences and customize the three most popular tools for formatting and checking code: the simple Prettier, the modern Biome, and the boundless ESLint.

By 
Maksim Kachurin user avatar
Maksim Kachurin
·
May. 29, 25 · Analysis
Likes (0)
Comment
Save
Tweet
Share
2.9K Views

Join the DZone community and get the full member experience.

Join For Free

It doesn't matter if you work alone or in a large team — code formatting should be uniform for all developers. It reduces noise and arguments about code style at code review, makes code more readable, and speeds up development by eliminating the need to manually format each line.

In this article we'll take a closer look at three of the most popular tools with detailed customization instructions.

Prettier

Prettier is the simplest code formatter on our list. It requires almost no customization, but because of that, it is very limited. It is an Opinionated code formatter, which means that it has its own opinion about how your code should look, and you cannot change it.

For me personally, it's not a good fit at least because it doesn't allow me to customize a number of important rules, such as Stroustrup bracket style (named after the creator of C++, Bjarne Stroustrup).

JavaScript
 
// With Stroustrup bracket style, conditions are always moved to the next line
if (condition) {
  ...
}
else {
  ...
}


Also, Prettier doesn't support code validation and won't tell you about possible errors, so you will have to use ESLint anyway, which will be discussed in the next sections.

Benefits of Prettier

  • Zero-config and easy installation
  • Popular and already included in many projects and templates
  • Supports many file formats
  • There is basic extensibility through the plugin system (mostly adding support for new formats)

Disadvantages of Prettier

  • Opinionated, which means it won't allow you to customize the style to your needs
  • Does not support linking files and requires ESLint to be installed and configured
  • In conjunction with ESLint, creates conflicts that need to be resolved through plugins

For installation, run the command:

Shell
 
npm install --save-dev --save-exact prettier


Note: The --save-exact flag tells npm that you want to pin to this version of the package and not update it each time you install dependencies.

Then create the .prettierrc file and configure parameters:

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


You can also create a .prettierignore file and specify which files it should ignore:

diff
 
**/node_modules
**/dist
**/build
**/public


Run the command to verify that Prettier is running:

Shell
 
npx prettier <files>


Prettier provides very basic code formatting capabilities and may not be suitable for many teams due to its limitations in customization. Nevertheless, I am ready to recommend it for small teams, quick-start projects, or contributors who don't want to configure anything.

Biome

Biome has a similar philosophy to Prettier — it is a simple, near-zero-config customization. It is also an opinionated formatter, so like Prettier, you should be prepared to trust the style of your code to the formatter's developers.

However, unlike Prettier, Biome gives you more possibilities to customize rules. The best part is that it already has a built-in linter, so it will not only format your code but also point out potential errors where simple formatting is not enough.

Benefits of Biome

  • Lightning-fast speed
  • More configuration options than Prettier. For example, automatic import ordering.
  • Zero-config and easy installation
  • Very active development and no Legacy configuration formats
  • Possibility to migrate from Prettier and ESLint with one command.

Disadvantages of Biome

  • Opinionated formatter, not all rules can be customized to your style
  • No support for many file formats and frameworks
  • Not enough linter rules, very inferior to ESLint at the moment
  • No plugin system (currently available only in beta version)
  • Only JSON config, which makes it difficult to create flexible rules depending on the environment and share configs between projects.

For installation, run the command:

Shell
 
npm i --save-dev --save-exact @biomejs/biome


Then run the command to create the default configuration file:

Shell
 
npx @biomejs/biome init


This will create a biome.json file with the default config file.

Edit the file by adding or removing the necessary rules. Example of my config:

biome.json

JSON
 
{
  "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
  "vcs": {
    "enabled": false,
    "clientKind": "git",
    "useIgnoreFile": false
  },
  "files": {
    "ignoreUnknown": false,
    "ignore": ["**/node_modules", "**/dist", "**/build", "**/public"]
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 120
  },
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "style": {
        "useBlockStatements": "error",
        "useConst": "error",
        "useTemplate": "error",
        "useSingleCaseStatement": "error"
      }
    }
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single",
      "trailingCommas": "es5",
      "semicolons": "always",
      "bracketSpacing": true,
      "bracketSameLine": false,
      "arrowParentheses": "always"
    }
  }
}


Run the command to verify that Biome is running:

Shell
 
npx @biomejs/biome lint <files>


If you are already using or have ever used Prettier and feel that it's enough for you, I would recommend that you definitely try Biome for more speed, flexibility and code linting.

ESLint + Stylistic

ESLint is primarily a code linter, not a formatter, but many rules have autofix mode and can be automatically fixed.

In general, if you care about the quality of your product and want to reduce the number of possible bugs at the development level, ESLint is a must for you, and if it's not your first project, you probably already use it.

Thousands of plugins have been written for ESLint to implement all sorts of code styles and file formats, and a hundred teams from big companies like Google and Airbnb have developed their own style guides, rules, and plugins for them, making the possibilities simply endless.

Benefits of ESLint

  • Fully flexible customization of any rules
  • Extensive plugin system
  • Linter first and foremost
  • Huge community
  • Industry standard

Disadvantages of ESLint

  • Quite heavy and slow, fixing issues can take a few seconds for heavy files
  • Difficult to configure, multiple config standards, customizing from scratch can be problematic, even with official instructions
  • Changing API, because of which old plugins may not work
  • Difficulties with upgrades, especially when changing major versions

We will set up ESLint with validation and formatting support for most formats and frameworks, including even CSS, with minimal setup and configuration. We do this with @antfu/eslint-config, which uses the official stylistic plugin for code formatting (as well as a number of other useful plugins).

For installation, run the command:

Shell
 
npm i --save-dev --save-exact eslint @antfu/eslint-config eslint-plugin-format


The command will install:

  • eslint – ESLint itself
  • @antfu/eslint-config – Replaces Prettier, includes recommended formatting rules, as well as Stylistic and Perfectionist. Supports linting JS, TS, TSX (React, Solid, Inferno, ...), Vue, Svelte, Markdown and many other default formats.
  • eslint-plugin-format – Adds the ability to format different file types such as HTML/CSS/SVG/Markdown/Astro, and so on. Fun Fact: Uses Prettier under the hood

Create a configuration file in the root of your project:

eslint.config.mjs

JavaScript
 
import antfu from '@antfu/eslint-config';

export default antfu({
  // Type of the project. `lib` will enable more strict rules for libraries.
  type: 'app',

  // Enable formatters support for CSS, SCSS, LESS, HTML, SVG, etc.
  formatters: true,
  
  // Enable TypeScript support
  typescript: true,
  
  // Enable JSX rules
  jsx: true,

  // Enable linting for **code snippets** in Markdown.
  markdown: true,

  // Disable linting for JSON files
  json: false,

  // Requires `eslint-plugin-solid`
  // solid: true,

  // Requires `@eslint-react/eslint-plugin eslint-plugin-react-hooks eslint-plugin-react-refresh`
  // react: true,

  // Requires `eslint-plugin-svelte`
  // svelte: true,

  // Enable Vue support
  // vue: true,

  // Requires `@unocss/eslint-plugin`
  // unocss: true,

  // Enable ASTRO support (requires eslint-plugin-astro)
  // astro: true,

  // Enable regexp rules (requires `eslint-plugin-regexp`)
  // regexp: true,

  // Enable TOML support
  // toml: true,

  // Enable unicorn rules
  // unicorn: true,
  
  // Enable ESLint-Stylistic
  stylistic: true,

  // Customize rules
  // https://eslint.org/docs/latest/rules
  // https://eslint.style/packages/default#rules
  rules: {
    'no-console': 'off',

    'style/no-multiple-empty-lines': ['error', { max: 2, maxEOF: 1, maxBOF: 0 }],
    'style/no-trailing-spaces': ['warn', { ignoreComments: true }],
    'style/space-before-function-paren': ['error', 'never'],
    'style/template-curly-spacing': ['error', 'always'],
    'style/indent': ['error', 2],
    'style/quotes': ['error', 'single'],
    'style/semi': ['error', 'always'],
    'style/brace-style': ['error', 'stroustrup'],
    'style/block-spacing': ['error', 'always'],
    'style/quote-props': ['error', 'as-needed'],
    'style/comma-dangle': ['error', {
        arrays: 'always-multiline',
        objects: 'always-multiline',
        imports: 'only-multiline',
        exports: 'only-multiline',
        functions: 'never',
    }],
    'style/object-curly-spacing': ['error', 'always'],
    'style/keyword-spacing': ['error', { before: true, after: true }],
    'style/space-infix-ops': ['error'],
    'style/member-delimiter-style': ['error', {
        multiline: {
            delimiter: 'semi',
            requireLast: true,
        },
        singleline: {
            delimiter: 'semi',
            requireLast: false,
        },
    }],
    'style/jsx-curly-spacing': [1, {
        when: 'always',
        allowMultiline: true,
    }],
  },

  // Ignore files
  ignores: [
    '**/node_modules',
    '**/dist',
    '**/build',
    '**/public',
  ],
});


I've reconfigured some of the rules to my liking, but for the sake of the example, just change the rules you're not happy with via the stylistic or rules parameters.

You can also include additional rules to validate specific file types. I left them in the comments in JSON, for example for additional SolidJS linter support run npm i -D eslint-plugin-solid and include solid: true in the config.

Run the command to verify that ESLint is running:

Shell
 
npx eslint <files>


How to Enable Autoformatting When Saving a File

Once you have chosen the right tool and configured it, I recommend that you enable automatic file formatting every time you save a file.

In VSCode-based editors (Cursor / Windsurf):

  1. Install the appropriate plugin (eslint / biome / prettier).
  2. Open VSCode Settings and type “Format” in the search field.
  3. Select your preferred formatter and specify what you want to format when saving and pasting.

Select default formatter


You can also open the “Open User Settings (JSON)” command and change these settings via the config file:

settings.json

JSON
 
// Eslint as default formatter
"editor.defaultFormatter": "dbaeumer.vscode-eslint",

// Biome as default formatter
// "editor.defaultFormatter": "biomejs.biome",

// Prettier as default formatter
// "editor.defaultFormatter": "esbenp.prettier-vscode",

// Format on save
"editor.formatOnSave": true,
// Format on paste
"editor.formatOnPaste": true,

// ESLint enable for this file types
"eslint.validate": [
  "javascript",
  "typescript",
  "typescriptreact",
  "javascriptreact",
  "json",
  "css",
  "markdown"
],

// You can also reassign rules for certain file types:
// Disable for css files
"[css]": {
  "editor.defaultFormatter": "dbaeumer.vscode-eslint",
  "editor.formatOnSave": false,
  "editor.formatOnPaste": false
}


In IntelliJ IDE-based editors (WebStorm, PHPStorm, PyCharm):

  1. Activate Prettier or ESLint in Settings → Languages & Frameworks → JavaScript. In case of Biome, you will need to install the Biome plugin first.
    Install the Biome plugin


  2. Next, activate the Run on Save option, or go to Settings → Tools → Actions on save and check the desired action.
    Run on Save option

Do not select several formatters at the same time!

Conclusion

In this post, we broke down the pros and cons and how to customize each of the tools presented: Prettier, Biome, and ESLint.

Prettier provides basic code formatting capabilities, but if you need more flexible settings, it may not suit you. Despite this, I am ready to recommend it for small teams, quick-start projects, or contributors who don't want to configure anything.

If you want to quickly start developing in a unified style and not think about customization, but you need a basic linter, perhaps Biome is the right option for you.

If you have a formed team, specific preferences in code style, and need the possibility of more precise and deep customization, ESLint is a great option. It can be customized with validation and formatting support for most formats and frameworks, so you'll get maximum code validation coverage and avoid many bugs.

Choose the tool that suits you best, but don't be afraid to try new things.

CSS ESLint Visual Studio Code

Opinions expressed by DZone contributors are their own.

Related

  • Static Analysis with ESLint and LWC
  • Why Tailwind CSS Can Be Used Instead of Bootstrap CSS
  • Maximizing Productivity: GitHub Copilot With Custom Instructions in VS Code
  • Exploring Intercooler.js: Simplify AJAX With HTML Attributes

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • [email protected]

Let's be friends: