Rome is a new set of tools for working with web-facing technologies like JavaScript, TypeScript, JSON, HTML, Markdown, and CSS. The toolchain currently supports linting and formatting, with active plans to also support bundling, compiling, minification, type checking, testing, and documentation generation. Rome aims to holistically enable all aspects of the modern web-focused development workflow. Such an ambitious tool may seem like a late April fool’s joke amidst the solution-overload of the JavaScript ecosystem, but the tool’s origins, its architecture, and its design principles demand to be taken seriously.
Current Ecosystem
Even for experienced developers, spinning up a new web-facing project is inevitably daunting today because of the tooling disparity that runs rampant throughout the JavaScript ecosystem. A mind-boggling amount of independent packages are required to manage modern code effectively: Babel for compilation, Webpack for bundling, PostCSS or SASS for CSS processing, Prettier for formatting, ESLint for JavaScript linting, StyleLint for CSS linting, Jest for testing, TypeScript for type checking, and the list goes on, and on, and on. A single player dominates each independent category of code management, and these packages can have unexplicit and poor interoperability between one another. Further, each tool is configured independently, which often results in duplicated configuration settings using a different syntax and file formats. New cross-tool integrations and fixes to existing integrations take time since different teams maintain each tool. It’s also common to encounter dependency issues between tools or their dependency graphs. Code management today takes time and effort and relies on piecing together many disparate tools in the hopes of forming a usable project foundation.
What is Rome?
Rome combines all aspects of code management into a single tool with zero external dependencies. Yes, you read that correctly, and it’s worth repeating for good measure: Rome aims to holistically replace many of the major tools that currently dominate the ecosystem, and it does so without the use of a single external dependency. Rome was created by Babel, Yarn, and Lerna creator Sebastian McKenzie, and it’s internally powered by a freshly implemented parsing core that resiliently generates immutable ASTs. Since many existing tools already rely on the same subset of core dependencies (think ESLint and Prettier both depending on Babel), the benefits of an all-encompassing tool become much more apparent.
Rome’s unified architecture offers unique advantages over traditional ad-hoc code management solutions. Offering a unified solution for tasks like linting, compiling, and type checking allows for faster execution, richer user-facing messaging, and more robust code fixes compared to piecing together independent linters, compilers, and type checkers. This cross-cutting architecture also allows Rome to safely deliver support for new features much faster than other solutions. For example, suppose browsers begin to support a new experimental CSS rule. In that case, a traditional project may have to wait for PostCSS, StyleLint, and Prettier to each independently add support for the new rule syntax, update each package version, and then verify that the packages still work together as expected. Because Rome provides unified CSS compilation, linting, and formatting, a Rome-powered project would only have to wait for Rome to add support for the new CSS rule. This cohesiveness between traditionally unrelated aspects of code management allows consumers to spend more time developing and less time worrying about honing and tweaking a bespoke project’s toolset.
Rome Philosophy
In order to effectively provide solutions to so many different project pain points, Rome is built with strict technical and philosophical goals in mind. From a technical perspective, Rome is built on top of a recoverable parser. This means that a valid AST is always generated regardless of any issues that may be detected while surfacing as many errors as possible at once. This mitigates the tediousness of uncovering new errors once existing errors are fixed, as is common when chaining independent tools together. Rome is also built on top of a portable cache that identifies artifacts using unique IDs rather than machine-specific file paths. This allows Rome caches to be easily shared between environments or even across networks in a machine-agnostic manner. Continuing with the idea of agnosticism, Rome relies on an HTML-like markup format for rendering output semantically to the terminal. This allows output to be rendered to various formats, including ANSI, HTML, and plain text. Rome is written using TypeScript with maximum type-safety in mind, and is entirely self-hosted, meaning it’s bundled, compiled, linted, and tested by itself.
Beyond its technical underpinnings, the Rome project as a whole strives to set forth explicit and clear expectations for what the tool will and won’t do. A cornerstone of Rome is its lack of external dependencies, and at no point in the future will Rome ever pull in any third-party package. Code errors surfaced by Rome should never be generic. They should always be clear and specific to the issue being surfaced, and they should always offer an actionable fix if applicable. Error messaging should always use inclusive terminology and should never rely purely on formatting cues to indicate failure or success. The user and developer-facing APIs offered by Rome should be constantly questioned and kept to a minimum. Verbose and clear naming conventions should always be favored over short abbreviations.
Conclusion
The idea of trusting a new tool like Rome with aspects of code management that highly-used, industry-dominating packages have traditionally handled is scary, and it can help to understand the tool’s origins. Sebastian McKenzie created prolific open-source software, including Babel, Yarn, and Lerna. These packages power most of the JavaScript ecosystem and are downloaded almost 2 billion times each year. Babel is arguably the most foundational package in the JavaScript ecosystem, and Sebastian coalesced all the knowledge and findings gained from writing Babel and improved upon these concepts to create Rome’s core. Many other tools besides Babel that dominate the industry, such as ESLint and Prettier, are just small functional layers that sit on top of Babel internally, making these tools straightforward to freshly implement (and functionally improve upon) within Rome. While the goal of Rome is ambitious, its breadth begins to logically make sense once the inherent interconnectedness of existing solutions becomes clearer.