Rome is a monolithic tool containing functionality that has traditionally been separate tools in the frontend ecosystem. We call this a toolchain. It is not a collection of existing tools, but completely custom, built largely from scratch, contained entirely in a single package and codebase.
We have significant implementations already for most components, including compiling, bundling, and testing, all using the same core abstractions and internal libraries. Rome is even self-hosted and we use them to build and develop Rome itself! Once usage as a linter has stabilized, we will move onto the unreleased features to prepare and generalize them for public usage.
Linting is an excellent low-risk way for us to mature and validate shared functionality like editor integration, configuration, parallelization, caching, parsing, and dependency analysis. It is not in the critical build path for development so is relatively straight forward and safe to adopt.
Even though this is a beta, we have support for over 100 lint rules, including the most common rules needed when working with TypeScript and React. See the full list of rules. You can expect a full featured experience, however may still encounter bugs. With most of the feature development out of the way we will be focusing primarily on stability.
Most of our rules have been inspired by their ESLint equivalents. This required a complete rewrite to utilize Rome’s API that differ extensively from existing tools. Without the amazing work of the ESLint team and community establishing these recommended patterns, we would not have been able to pull this off. Refer to the lint rule docs for direct references.
Since open sourcing, at the beginning of the year, we have received contributions from over 70 contributors and 600 pull requests. We have an established team, and a code of conduct enforcement policy. This ensures transparency around project decisions, moderation, and direction.
You can read more about Rome, including how to get started, in our documentation. If you would like to get involved, check out our contributing instructions. If you are interested in reading more about the history and rationale for the project, you can continue reading below.
But we think we can go even further. Babel should be able to power minifiers, linters, formatters, syntax highlighters, code completion tools, type checkers, codemod tools, and every other tool to be using the same foundation to do their job better than ever before.
In 2016, I left the project, and those plans never materialized. Over time, I learned the Babel would not have been able to successfully adapt to execute on this vision anyway. The solution to plugins was “expose all the internals” which is an extremely large API surface area to maintain and restricts your ability to make any changes.
Making the necessary modifications to Babel to allow for it to be a reliable base for other tools would have required changes to absolutely everything. The architecture is bound to the initial design choices I made in 2014 when I was learning about parsers, ASTs, and compilers.
There would have been no way to provide backward compatibility, and with expectations already set, any significant changes to the project would have introduced an extremely high amount of ecosystem churn.
In an ode to the Ship of Theseus, if all components of an object are replaced, is it the same object? There is far less confusion and friction to release something entirely new than drastically change something that’s already in widespread usage. I had since moved on from the project, and so any evolution would not have been possible, and would have required complete vision alignment.
Even though I wasn’t involved in Babel, I still maintained a presence in the developer tooling ecosystem. I eventually went on to develop other tools like Yarn and be involved in projects like Prepack and Flipper. This work continued to develop the ideas that would eventually become Rome and shaped my philosophy on developer experience. A focus on excellent errors, clean user interface, and minimal configuration.
Language tooling maintainers spend so much time working on the same things. Processing source code, whether it’s in a transpiler like Babel, linting it in ESLint, or bundling it in webpack, is fundamentally the same problem with overlapping responsibilities and technical implementation.
I had always maintained private repos where I would experiment with ideas, but the original code that would become Rome was started at the beginning of 2017 while I was working for Facebook in my free time. I continued iterating and experimenting on the idea and building out all the different pieces, until 2019, when I was given the opportunity to work on and explore using it at Facebook full-time.
I eventually left Facebook and the project became open source in February 2020 where I would continue it as an independent community-driven project.