Intermediate 7 terms

Monorepo & Build Systems

Turborepo, Nx, Bazel vocabulary: pipeline caching, affected commands, workspace management, hermetic builds, and trunk-based development in monorepos.

  • Monorepo /ˈmɒnəʊˌriːpəʊ/

    A single version control repository containing multiple projects (applications, libraries, services) with shared tooling, dependencies, and build infrastructure. Contrasts with polyrepo (one repo per project).

    "We migrated from 15 separate repos to a monorepo. Benefits we saw immediately: atomic changes across library and consumers (one PR instead of 5), shared ESLint and TypeScript config, automatic detection of which services are affected by a change. The trade-off: the CI pipeline is more complex and initial clone is large."
  • Turborepo Pipeline /ˈtɜːbəʊˌriːpəʊ ˈpaɪplaɪn/

    Turborepo's task orchestration: a graph of tasks with dependencies. Configured in turbo.json: task A dependsOn: ['^build'] means A must run after all upstream package builds. Turborepo runs tasks in parallel where the graph allows.

    "Our Turborepo pipeline: build depends on ^build (upstream packages first), test depends on build, lint has no dependencies (runs in parallel with build). Running turbo run build test from the root spawns parallel builds across 12 packages, only waiting for upstream dependencies. Total CI time dropped from 18 minutes to 4 minutes."
  • Remote Cache (Turborepo / Nx) /rɪˈməʊt kæʃ/

    A shared artifact cache for build and test outputs. When the cache key (source files + env hash) matches, the task output is downloaded from the cache instead of re-run. Developers and CI share the same cache — a build run in CI is available for developers to restore locally.

    "With Turborepo remote cache, a developer pulling a branch that CI already built gets cache hits for all unchanged packages. Our average developer build time went from 8 minutes to 40 seconds — the only work done locally is for the changed packages. Cache keys are deterministic: source files + env variables + OS hash."
  • Affected Commands (Nx) /əˈfɛktɪd kəˈmɑːndz/

    Nx commands that determine which projects are affected by changes since a base branch. Only runs tasks on the affected subset, skipping unchanged packages. Uses the project dependency graph to find transitive dependents.

    "In CI we run nx affected --target=test --base=main. If I changed the shared-utils library, nx calculates: api-service (imports shared-utils) is affected, frontend (also imports shared-utils) is affected, auth-service (no dependency) is not affected. Only the affected packages' tests run — CI takes 3 minutes instead of 20."
  • Hermetic Build (Bazel) /hɜːˈmɛtɪk bɪld/

    A build that is completely isolated and reproducible — it only uses declared inputs (source files, dependencies), has no access to the network or file system outside the sandbox, and produces identical outputs given identical inputs. Bazel enforces hermetic builds by design.

    "Bazel enforces hermeticity: a BUILD rule can only use files declared in its deps or srcs. An accidentally imported dependency that's not declared causes a build failure — you can't rely on a file that happens to be on the build machine. This catches 'it works in CI but not locally' issues caused by undeclared dependencies."
  • Starlark (Bazel) /ˈstɑːlɑːk/

    The scripting language used for Bazel BUILD files and .bzl extension rules. A subset of Python: deterministic, no I/O, no random, pure functions. Enables custom build rules and macros.

    "We wrote a custom Starlark macro proto_and_grpc_library that wraps the proto_library and grpc_library rules — every service BUILD file uses it with three lines instead of twenty. Starlark's restrictions (no I/O, no side effects) mean BUILD files are safe to evaluate in any order and cache their outputs."
  • Trunk-Based Development /trʌŋk beɪsd dɪˈvɛləpmənt/

    A branching strategy where all developers integrate their changes directly to the main branch (trunk) daily, using short-lived feature branches (hours to days, not weeks). Feature flags enable incomplete features to be merged without exposing them to users.

    "In our monorepo we practice trunk-based development: no feature branches longer than 2 days. Incomplete features are merged behind feature flags. This eliminated merge hell (3-week branches with massive conflicts) and means main is always deployable. The key enabler: a fast, reliable CI that catches issues before merge."