Announcing Rome v12
The Rome team is happy to announce Rome version 12. This new version brings JSON support, new lint rules, import sorting and more!
You can upgrade Rome by running the following command:
npm install --save-dev --save-exact rome@12.0.0
pnpm update --save-exact rome@12.0.0
yarn upgrade --exact rome@12.0.0
Or install the VS Code extension to integrate Rome into your editor.
JSON file support
Rome now supports JSON files. This is a very exciting feature because it opens various toolchain features.
You can format JSON files via CLI or LSP (VSCode extension). You can now avail of Rome’s diagnostics when parsing JSON files.
For example, let’s use as an example an invalid JSON file:
{
"something": [hey,
"true"
]
}
Here’s Rome’s diagnostics

Diagnostic emitted by Rome via LSP

Diagnostic emitted by Rome via CLI
The JSON parsing provides the same infrastructure as JavaScript: excellent diagnostics and error recovery.
TypeScript 4.7 and TypeScript 5.0 support
Now Rome supports all the new features introduced by TypeScript 4.7 and TypeScript 5.0!
Support for optional variance annotation:
type Foo<in T> = {};
type Foo<out T> = {};
Support for extends
constrain on infer
type FirstString<T> =
T extends [infer S extends string, ...unknown[]]
? S
: never;
Support for const type parameters
function a<const T>() {};
Support for export type *
export type * as vehicles from "./vehicles";
Import sorting via CLI (experimental)
With Rome v11, we gracefully introduced the possibility of sorting import statements via the VSCode extension. With this release, we now expose this feature via CLI via the rome check
command.
This feature is opt-in and disabled by default, hence the experimental.
You can opt-in via configuration:
{
"organizeImports": {
"enabled": true
}
}
The import sorting is part of our analyzer infrastructure, and it’s not part of the formatter. There are a few reasons why:
- the semantics of the import statements differ by language;
- some languages, like JavaScript, have side effects; hence they require a static analysis to make sure that changing the order of the statements is safe;
As for this release, import sorting doesn’t have any particular configuration. We plan to add more options in the coming releases.
You can apply the sorting via rome check --apply-unsafe
. Please refer to the documentation for more information.
Configuration enhancements
The configuration is an entry point where the user can communicate with a tool; hence it requires special care. With this release, we added some new features that should make the user’s experience better.
Better diagnostics and recovery
Before, Rome used serde
to parse the configuration file and map it to an internal object. This had one downside: a syntax error would have caused to fail the whole toolchain.
While this behaviour is well expected from most of the tools, sometimes this is annoying because a missing comma (a typo) might cause a major failure.
With this release, Rome uses its own internal JSON parser to deserialize the configuration file; this gives many pesky features!
A syntax error won’t fail the whole toolchain, thanks to the error recovery of the parser.
Rome will apply its defaults to the sections with errors, but it will keep the configuration settings for the correct parts. Rome has complete control over the validation of the configuration, which allows emitting excellent diagnostics with contextual suggestions.

Diagnostic when there’s an invalid in rome.json
The new configuration diagnostics are available via LSP too!

Diagnostic for incorrect configuration
Auto discovery
Rome can now auto-discover a configuration file. If a configuration file is not present in the current working directory, Rome will attempt to traverse the parent directories until it finds a rome.json
file or there aren’t any more directories to traverse.
Tell Rome where to find the configuration file
With a new CLI argument called --config-path
, you can now tell Rome where to find the rome.json
file. When this option is passed, Rome won’t attempt to auto-discover the configuration file.
VSCode extension: better control
Rome aims to be a suitable LSP by providing hints, suggestions, auto competition, etc. Some of these features are far from being done, but it’s already able to analyze each document and provide meaningful diagnostics when a document is open.
While the vision might seem friendly, sometimes this could create noise, especially if users open projects that don’t use Rome at all.
Users requested a way to turn off Rome without disabling the extension. We added a new option called Require Configuration
. When enabled, Rome won’t attempt to analyze any document without a configuration file.
More linter goodies
This release adds new configurations to the linter, new rules, and promoted nursery
rules.
New options
There’s a new option to enable or disable all rules or all rules that belong to a group.
Enable all rules
Rome will enable all rules, even the ones that belong to nursery
group:
{
"linter": {
"enabled": true,
"rule": {
"all": true
}
}
}
Only some rules
Rome will disable all rules and enable only the rules that belong to correctness
group:
{
"linter": {
"enabled": true,
"rule": {
"all": false,
"correctness": {
"all": true
}
}
}
}
A new language option allows you to ignore global names:
{
"linter": {
"enabled": true
},
"javascript": {
"globals": ["$"]
}
}
With this option, lint rules will take ignore the variable $
. For example, the rule noUndeclaredVariables
won’t emit any diagnostic.
Rules
Rules that are now stable:
lint/correctness/noUnsafeFinally: makes sure that the block
finally
is always calledlint/correctness/noConstructorReturn: prevents
return
inside aconstructor
lint/correctness/noPrecisionLoss: prevents conversation that might result in loss of precision
lint/correctness/noVoidTypeReturn: prevents returning something inside functions that return
void
For example:
function f(): void { return undefined; }
Would trigger the rule.
lint/correctness/noStringCaseMismatch: prevents possible mismatches when using
toLowerCase
ortoUpperCase
For example:
if (foo.toUpperCase() === "Foo") {}
Would trigger the rule, because the string “Foo” contains lower case characters.
lint/style/useEnumInitializers: forces to initialize each variant of an enum
For example:
enum Priority { Low, Medium, High = 100 }
Would trigger the rule because
Low
andMedium
are not initialized.lint/suspicious/noConstEnum: disallow the use of
const enum
Acknowledgements
- realtimetodie, they added the new
--config-path
argument, and solved many issue in our file explorer. - nissy-dev, they worked on implementing all the new TypeScript features!
- denbezrukov, they worked on various parts of the toolchain: LSP, parser, formatter and more!
- Conaclos, they made massive amount of contributions around the linter: new rules, fixes around existing rules, better documentation and onboarding new contributions.