Skip to main content

The Rome Toolchain

About Rome

Rome is a formatter, linter, bundler, and more for JavaScript, TypeScript, JSON, HTML, Markdown, and CSS.

Rome is designed to replace Babel, ESLint, webpack, Prettier, Jest, and others.

Rome unifies functionality that has previously been separate tools. Building upon a shared base allows us to provide a cohesive experience for processing code, displaying errors, parallelizing work, caching, and configuration.

Rome has strong conventions and aims to have minimal configuration. Read more about our project philosophy.

Rome is written in Rust.

Rome has first-class IDE support, with a sophisticated parser that represents the source text in full fidelity and top-notch error recovery.

Rome is MIT licensed and moderated under the Contributor Covenant Code of Conduct.

Getting Started

Rome works on Linux, macOS, and Windows.

For all operating systems, we support both x86_64 and ARM architectures.

Install Rome using any of the following methods.

Install official Rome VS Code extension

You can use Rome by installing the VS Code extension from the marketplace.

Rome currently doesn’t support other editors than VS Code. Let us know if you would like support for another editor.

Install Rome CLI

Install rome using your preferred node package manager. We require a minimum Node version of v14.18.

NOTE: we recommend not installing the binary globally, instead please install the binary locally to your project. You can also use npx, pnpm dlx or yarn dlx to run [email protected].

Package manager Instructions
npm npm i -D [email protected]
pnpm pnpm add -D [email protected]
yarn yarn add -D [email protected]

If you install the CLI locally, use the scripts field of your package.json to run Rome. For instance:

"scripts": {
"format": "rome format ."

Then you can run:

npm run format
yarn format
pnpm format

Install Rome in your CI pipeline

GitHub Actions

Please refer to the setup-rome action documentation for more information about its configuration:

- uses: rome/setup-[email protected]
version: latest
- run: rome --help

Installation on any other CI

You can download and install the binary directly using curl:

curl -L<OS>-<ARCH> -o rome
chmod +x rome

Where <OS> and <ARCH> follow the Node.js syntax convention:

  • <OS> is one of the following values: win32, darwin or linux
  • <ARCH> is one of the following values: arm64 or x64

NOTE: For Windows Subsystem for Linux (WSL), please use linux as your OS

win32 darwin linux
arm64 win32-arm64 darwin-arm64 linux-arm64
x64 win32-x64 darwin-x64 linux-x64

Please make sure to choose the correct architecture from the releases page.


Development Status

Rome is being rewritten in Rust, so it doesn’t support all the intended features.

Rome is currently only supported as a formatter for JavaScript and TypeScript.**

We plan on covering the following areas:

  • Bundling
  • Compiling
  • Documentation Generation
  • Formatting
  • Linting
  • Minification
  • Testing
  • Type Checking
  • … and more

Language Support

Language Parsing Formatting Linting
JavaScript 🚫
TypeScript 🚫
JSX ⌛️ 🚫
JSON 🚫 🚫 🚫
HTML 🚫 🚫 🚫
CSS 🚫 🚫 🚫
Markdown 🚫 🚫 🚫

JavaScript support

Rome supports only the official syntax. The team starts developments of the new syntax when a proposal reaches Stage 3.

Rome supports ES2022 version of the language.

TypeScript support

Rome doesn’t support decorators (the old proposal). Rome’s parser will ignore them as if they were comments. This means that programs with decorators are still valid, but they won’t benefit all the underlying features such as formatter, analyzers, etc.


You can use the formatter via our VS Code extension or by downloading our CLI directly from our release page.

WARNING: The CLI and VS Code extension are packaged with separate binaries, which means that if you don’t use our default options, you will have to pass them to both the extension AND the CLI.

This is a temporary choice to allow people to play with our formatter. This will change in the near future.

Formatter options

Our formatter is really strict and has support for only a few options:

  • indent style, you can choose between tabs or spaces; Rome’s default is tabs
  • quantity of spaces, applied only if you choose spaces as indent style;
  • line width, which is the number of characters that fit in a single line; Rome’s default is 80

VSCode extension

The extension allows you to change the default formatter options.

For easy access to the available options, navigate to the settings menu of the VSCode extension and type: @ext:rome.rome.

Plus, you can try an additional feature that allows you to format code with syntax errors.

This is an opt-in feature that allows developers to experiment with a formatter that can work with an error resilient parser.

WARNING: all options are marked as BETA because this might change, once we will add support of a configuration file

If you want to set Rome as your default formatter, you can do so by opening the command palette and select Format Document With ... , then Configure Default Formatter and finally select Rome. The option will appear only for documents that Rome supports.

Use the formatter with the CLI

The only command that is supported is format.

You can start by running the CLI with the --help flag:

rome format --help

Which will show you the options available at the moment:

Rome Formatter

rome format [OPTIONS] <INPUTS...>

INPUTS can be one or more filesystem path, each pointing to a single file or an entire directory to be searched recursively for supported files

--write Write the output of the formatter to the files instead of printing the diff to the console
--ci Enable CI mode, lock files and exit with an error if the formatter would modify them
--skip-errors Skip over files containing syntax errors instead of returning an error
--indent-style <tabs|space> Determine whether the formatter should use tabs or spaces for indentation (default: tabs)
--indent-size <number> If the indentation style is set to spaces, determine how many spaces should be used for indentation (default: 2)
--line-width <number> Determine how many characters the formatter is allowed to print in a single line (default: 80)
--quote-style <single|double> Determine whether the formatter should use single or double quotes for strings (default: double)


There are times when a developer wants to keep a specific formatting.

You can achieve this by adding a suppression comment right before the syntax node (expressions, statements, etc.).

Suppression comments have the following format:

// rome-ignore format: <explanation>


  • rome-ignore is the start of a suppression comment;
  • format: suppresses the formatting;
  • <explanation> is an explanation why the formatting is disabled;

Here’s an example of how a code will look like before and after the formatter does its job:

Before running the formatter

const   expr   =
// rome-ignore format: the array should not be formatted
(2*n)/(r-l), 0, (r+l)/(r-l), 0,
0, (2*n)/(t-b), (t+b)/(t-b), 0,
0, 0, -(f+n)/(f-n), -(2*f*n)/(f-n),
0, 0, -1, 0,

const expr = [
(2*n)/(r-l), 0, (r+l)/(r-l), 0,
0, (2*n)/(t-b), (t+b)/(t-b), 0,
0, 0, -(f+n)/(f-n), -(2*f*n)/(f-n),
0, 0, -1, 0,

After running the formatter

const expr =
// rome-ignore format: the array should not be formatted
(2*n)/(r-l), 0, (r+l)/(r-l), 0,
0, (2*n)/(t-b), (t+b)/(t-b), 0,
0, 0, -(f+n)/(f-n), -(2*f*n)/(f-n),
0, 0, -1, 0,

const expr = [
(2 * n) / (r - l),
(r + l) / (r - l),
(2 * n) / (t - b),
(t + b) / (t - b),
-(f + n) / (f - n),
-(2 * f * n) / (f - n),

As you can see the first array, which has a suppression comment, is left untouched!

Differences with Prettier/dprint

Our formatter uses a CST to implement its algorithms, as opposed to Prettier or dprint, which use an AST. This means that it has to deal with a different set of problems e.g. comments and how to place them.

As you might know, comments can appear almost everywhere inside a program, which can make the implementation of a formatter more difficult.

In a CST, comments are attached to tokens, so it’s possible to extract this information when inspecting a single node.

Considering these assumptions, the Rome team had to create some heuristics and concepts in order to consistently format comments inside a program.


The placements of some comments might be different, for example in JavaScript functions and JavaScript classes.

A function has a “head” and a “body”:

  • the head is where we define the name of the function and its signature (its parameters, return type, etc.);
  • the body is where we define the implementation of the function, usually - but not only - inside a block {};

Our formatter marks a function head as a hard group, while the body is a normal group. This means that all the comments inside the head are “pushed out” and moved outside it, making the formatting always consistent.

Here’s an example against Prettier/dprint, we place comments inside the head of a function:

function // something
a(b, c) {
let a = "f";

function a(b, c) // something
let a = "f";

This how Rome and Prettier format this code:

// Rome
function a(b, c) {
// something
let a = "f";

function a(b, c) {
// something
let a = "f";

// Prettier/dprint
function // something
a(b, c) {
let a = "f";
function a(b, c) {
// something
let a = "f";

Please check our playground and its result

Migration from other formatters

Rome doesn’t support a lot of options like other web formatters, which means that particular styles won’t be available to all developers.

To migrate from suppression comments of the old formatter, it’s recommended to run a global search and replace against the code base and replace the formatting comment with:

// rome-ignore format: migration from <name_of_former_formatter>

Then, you are free to change the reason of the suppression that you want.

Run the formatter and make sure that the code that was ignored is still the same.


This list includes general ethos the project should abide by. This list is not comprehensive. Some of these are obvious but are stated for completeness.


  • Errors should suggest fixes and hints where possible. These should be inferred and filtered from usage to reduce surfacing irrelevant and unhelpful messages.
  • Unique and specific error messages. No generic error messages. This not only helps users understand what went wrong, but should provide maintainers with a unique call site and the necessary information to debug.
  • Minimize API. Question the existence of all options and flags. Are they necessary? Can they be combined? How can we reduce code branching?
  • Reduce jargon. Don’t assume that users will understand specific terminology. Strive to provide clear meaning for experts and beginners. For example, use “character” where you would traditionally use “token” when producing parser errors.
  • Utilize verbosity when naming commands and flags. No unnecessary and confusing abbreviations.
  • Use inclusive terminology. Use gender-neutral pronouns. No ableist slurs. No usage of terms that could be considered insensitive.
  • Build for generic clients. Don’t assume that output will only be consumed by a terminal and using ANSI codes. Use abstractions that could be generalized for viewing in an IDE, browser, or other environments.
  • Terminal output should be unambiguous. When designing terminal output, don’t purely rely on formatting cues such as color. Always use a combination of formatting, symbols, and spacing. If all ANSI codes are stripped, all the output should still be understood.

 Filename:Line:Columnpages/UserLoginPage.js:8:8 Categorylint/jsx-a11y/altText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Message  × Provide alt text when using img, area, input type='image', and object
Code Frame     6  return <span className="App">
     7      <header className="App-header">
   > 8        <img src={logo2} className="App-logo" />
     9        <p>
    10          Edit <code>src/App.js</code> and save to reload.
Advice  i Meaningful alternative text on elements helps users relying on screen
    readers to understand content's purpose within a page.