Turborepo 1.2: High-performance build system for monorepos

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • WorkOS - The modern identity platform for B2B SaaS
  • SaaSHub - Software Alternatives and Reviews
  • turborepo

    Discontinued Incremental bundler and build system optimized for JavaScript and TypeScript, written in Rust – including Turborepo and Turbopack. [Moved to: https://github.com/vercel/turbo]

  • Turborepo author here...

    > * tasks on the root package (e.g. tsc -b that typechecks all packages)

    We are working on this as we speak! The first step is to add the ability to restrict hashing `inputs`[1] to the Turborepo `pipeline`. After that we are going to be adding root task running in the next minor release.

    However, as your monorepo grows, you will likely want to move away from running tasks like tsc from the root and instead run them on a per-package basis. The reason is that tools like Bazel, Buck, Turborepo, etc. can become more incremental (and thus faster) as your dependency/task graph becomes more granular (as long as you maintain or reduce the average affected blast radius of a given change). The other argument against root tasks is that they break hermeticity and encapsulation of the package abstraction. That being said, root tasks are very useful for fast migration to Turborepo and also for smaller repos. Futhermore, we're happy to tradeoff academic purity for productivity with features like this.

    > treat tasks such as lint:eslint, lint:pretter as a single task lint (or maybe lint:)

    You can run multiple tasks at the same time and Turborepo will efficiently schedule them at max concurrency.

    turbo run eslint prettier --filter=@acme/...

    However, it sounds like you like to see glob fan out of tasks. This is a really cool idea. I created a GitHub issue for it here [2] if you'd like to follow along.

    [1]: https://github.com/vercel/turborepo/pull/951

  • nix

    Nix, the purely functional package manager

  • InfluxDB

    Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.

    InfluxDB logo
  • nixpkgs

    Nix Packages collection & NixOS

  • The primary difference is that in Nix it's fairly easy to wrap arbitrary build systems, so you can inject third-party dependencies into your codebase without vendoring and adapting their build system (plus, through nixpkgs[0], the majority of all relevant software has already been wrapped).

    In Bazel you have to do a lot of that work yourself. Google has essentially ~unlimited manpower to do this for the things in their third_party tree, but for any other size of organisation this is not the case and people resort to all sorts of ugly hacks.

    Depending on your needs these things can also coexist with each other. To use an example from my work, we have a Nix-native build system for Go[1] and code using this[2] co-exists with code that just uses the standard Go build system[3]. Both methods end up being addressable on the same abstraction level, meaning that they both turn into equivalent build targets (you can see both in a full build[4] of our repo).

    And for what it's worth, some of the things Bazel gets extremely right (such as having a straightforward mapping from code location to build target, universal build command) are pretty easy to do in Nix (see readTree[5], magrathea[6]).

    [0]: https://github.com/NixOS/nixpkgs

    [1]: https://code.tvl.fyi/about/nix/buildGo

    [2]: https://cs.tvl.fyi/depot/-/blob/ops/besadii/default.nix

    [3]: https://cs.tvl.fyi/depot/-/blob/third_party/gerrit-queue/def...

    [4]: https://buildkite.com/tvl/depot/builds/13067

    [5]: https://cs.tvl.fyi/depot/-/blob/nix/readTree/README.md

    [6]: https://cs.tvl.fyi/depot@f0e6d3498d6c0f905977ea9432c311b6808...

  • rules_nodejs

    NodeJS toolchain for Bazel.

  • > Is Bazel designed in a way that make it impossible to do JS monorepos well?

    Not impossible, but you really need to go all in with it and follow its conventions and practices. See this for the main docs: https://github.com/bazelbuild/rules_nodejs

    One thing in particular that doesn't work well in the bazel world is doing your own stuff outside its BUILD.bazel files. If you're used to just npm install and jam some code in your package.json scripts... that doesn't usually work in the bazel world. If you have a lot of logic or tools in your build you'll likely need to go all in and make bazel starlark rules or macros that recreate that logic. Nothing is impossible, but expect to spend time getting up to speed and getting things working the bazel way.

  • jazelle

    Incremental, cacheable builds for large Javascript monorepos using Bazel

  • Yes, it's possible. At Uber we run a 1000+ package monorepo w/ Bazel and Yarn. Someone else mentioned rules_nodejs if you want to go with the popular option that is more or less in line with the Bazel philosophy[0]. We use a project called jazelle[1] that makes some different trade-offs that lets us do some interesting things like not busting the whole world's cache when lockfile changes, and source code generation (including automatic syncing of BUILD files to package.json)

    [0] https://news.ycombinator.com/item?id=30959893

    [1] https://github.com/uber-web/jazelle

  • WorkOS

    The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.

    WorkOS logo
NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts