Why oneRepo
oneRepo is a suite of tools for managing JavaScript and TypeScript monorepos, with the goal of enabling speed and confidence for all changes.
Tenets
Section titled Tenets- Documented: All commands and options must be documented and respond to
--help
requests. - Discoverable: Code for commands must be easy to find and trace in a familiar language.
- Clear output: All log output must be grouped, labelled with purpose, and clearly defined by its state.
- Correct: Avoid human errors by automating correctness checks whenever possible.
- Fast: Reduce wait time and overhead.
Features
Section titled FeaturesOther monorepo tooling is often either overly complicated or lacking in functionality, making it challenging for distributed organizations to maintain a healthy monorepo. To ensure conformance, stability, and discoverability, organizations need a tool that strikes the right balance, which existing solutions often fail to provide.
Automating tasks
Section titled Automating tasksoneRepo simplifies automation by handling common tasks for you and your team. Say goodbye to spending excessive time tinkering with tooling and hello to focusing on your applications.
Strict safety & checks
Section titled Strict safety & checksGone are the days of manually configuring file glob patterns for Workspace integrity and decision making for whether or not checks and tasks must run. oneRepo automatically and accurately determines which Workspaces, tasks, and checks are necessary for any given change
Stop recompiling dependencies
Section titled Stop recompiling dependenciesWith oneRepo, you can utilize shared Workspaces as source-level dependencies. This means that all import/require chains within the monorepo originate from the source files, eliminating the need to rebuild shared packages to capture changes.
Not another language
Section titled Not another languageoneRepo and its APIs, plugins, and configurations are all written in JavaScript (and TypeScript). There’s no need to learn a new language or decipher YAML/JSON schema DSLs to configure your tooling.
Human-readable output
Section titled Human-readable outputLogging output from every command and tool in oneRepo is carefully grouped, documented, and prevented from overlapping parallel executions. Every line includes context, timing, and log-type information.
No upsells
Section titled No upsellsOnce you’ve installed oneRepo, you’re all set. There’s no need to pay extra for additional features; simply bring your own infrastructure and enjoy the full feature set.
And more!
Section titled And more!Alternatives & pitfalls
Section titled Alternatives & pitfallsWhen considering tools for managing JavaScript repositories, it’s essential to be aware of common pitfalls.
Script overload
Section titled Script overloadOne such pitfall is script overload, where many tools require you to write individual commands into each Workspace’s package.json
"scripts"
field. This approach can lead to a brittle setup, copy-paste boilerplate, reduced reusability, and limited documentation and discoverability.
Take, for example, the following a real-world portion an application’s package.json
file that contained 43 different scripts just for running Cypress tests. None of these scripts are documented, and many of them may be completely or nearly identical, leading to confusion and inefficiency.
The phenomenon of an excessive number of scripts cluttering the package.json
file is what we refer to as “script overload”. This not only makes it challenging to remember how to run scripts in individual Workspaces but also highlights a broader issue with documentation and tooling standards.
Documentation Challenges
Section titled Documentation ChallengesMany tools lack proper documentation for package.json
scripts, making it difficult for developers to share, understand, and use their own tools effectively.
This lack of documentation also extends to other tooling, which often relies on memory, rather than providing an immediately accessible reference.
Pitfalls of npm Scripts
Section titled Pitfalls of npm ScriptsOther tools encourage script overload through task chaining – an approach that requires defining individual and separate scripts for building modules with various definitions (ESM, CJS, TS), resulting in complex and cumbersome configurations.
While these approaches may seem manageable at first, as repositories grow and become more complex, Workspaces may require unique configurations and conditional checks. Using a DSL (Domain Specific Language) or similar implementation adds another layer of complexity, requiring developers to either learn new concepts or rely on dedicated teams to build infrastructure.
Cache inconsistency
Section titled Cache inconsistencyUtilizing cached responses based on a set of input files can significantly reduce unnecessary work. However, the challenge lies in understanding precisely which files and workspaces affect the cache for each task, a responsibility that falls on you and your team. But even the best developers can easily make a configuration mistake that leads to difficult to debug problems.
The main issue with cache-based solutions is the need to maintain knowledge of the inputs and outputs for each task or target, especially when making substantial changes. It becomes crucial to ensure that any modifications do not unintentionally alter your tool’s determinism without updating the configuration. Given the complexity of modern projects, expecting every team member to be aware of all these details at all times is unrealistic, leading to potential oversights and confusion.
Here’s an example problematic configuration:
Can you spot where the previous build task may have issues with cache consistency? It’s okay if you aren’t sure, because there isn’t enough information yet.
Using the previous configuration, what if we also take a look at the ./tsconfig.json
?
Take a moment to look again and see if you can spot the issue. It’s not immediately obvious.
…
Hint: let’s highlight the important part at line 2 from the tsconfig.json
and compare to the namedInputs
in the nx.json
:
Identifying potential issues with cache consistency in a build task can be challenging without sufficient information, as seen in the example provided. For instance, consider the impact of changes made to the ./tsconfig.json
file. The configuration in tsconfig.json may include references to files outside of the local workspace, such as ../../shared/tsconfig/base.json
, which are not declared as inputs for cache consistency in nx.json.
In the event of modifications to the compilerOptions
within ../../shared/tsconfig/base.json
, it would be necessary to perform a full build of my-project without using the cache. However, due to the configuration approach in other monorepo tools like Nx and Turbo, overlooking or misconfiguring these dependencies is a common pitfall.
Confusing output
Section titled Confusing outputOne big frustration with other tooling is that the log output is difficult for humans to read – particularly when running tasks in parallel. Most monorepo tooling will buffer everything immediately to the output, interleaving parallel task output together, making it difficult to follow what is happening and where there may be issues or all is fine.
oneRepo solves for this by waiting grouping output by individual task. While running, by default, only the most recent or most important information will be shown. Output will never be interwoven between individual tasks. And without manually requesting more verbose output, superfluous information will be hidden:
History
Section titled HistoryoneRepo is inspired by closed source implementations at major companies like Twitter, Zillow Rentals, and Microsoft for Startups.