Using TypeScript Project References to Solve Common Package Issues in a Monorepo

The article explains how a frontend team tackled monorepo challenges—such as ignored package.json, tsconfig, and phantom dependencies—by adopting TypeScript Project References and minimal Git‑hook compilation, providing step‑by‑step configuration and code examples for seamless common package integration.

ByteDance Dali Intelligent Technology Team
ByteDance Dali Intelligent Technology Team
ByteDance Dali Intelligent Technology Team
Using TypeScript Project References to Solve Common Package Issues in a Monorepo

The Dali Intelligent Frontend team shares their monorepo journey, starting from the first commit in December 2018 to a repository now containing 154 business packages, 11 shared packages, and 7 tooling packages, and uses this article to record the lessons learned.

In their monorepo, developers often import common packages directly, adding them to the build tool's include list and treating their source as part of the business code. This leads to several hidden problems: the common package's package.json entry is ignored, its tsconfig.json is overridden by the consuming package, and dependencies declared only in the common package become phantom dependencies, causing version uncertainty.

Two practical solutions are discussed. The first, an automatic compilation via a Git pull hook, compiles all common packages on each pull but requires developers to restart dev processes when both common and business packages change. The second, leveraging TypeScript Project References , allows each package to be compiled independently while respecting their own tsconfig files, and is supported by ts-loader from version 5.2.0 onward.

Implementation steps include:

Ensuring the common package has correct TypeScript configuration, possibly providing separate tsconfig.es.json and tsconfig.lib.json files.

Adding a proper package.json with fields like exports, main, module, and typings (see code example below).

Adjusting the consuming package's build configuration: removing unnecessary includes, enabling projectReferences in ts-loader, and clearing conflicting compilerOptions.

Declaring the common package as a dependency in the business package's package.json so the package manager resolves it correctly.

Adding the common package's tsconfig paths to the references array of the business package's tsconfig.json (see code example below).

// package.json of a common package
{
  "name": "@monorepo_workspace/common-a",
  "version": "1.0.0",
  "description": "A common package",
  "sideEffects": false,
  "exports": {
    ".": {
      "import": "./es/index.js",
      "require": "./lib/index.js"
    }
  },
  "main": "./lib/index.js",
  "module": "./es/index.js",
  "typings": "./es/index.d.ts"
}
// ts-loader configuration snippet
tsLoader: (config) => {
  config.projectReferences = true;
  config.compilerOptions = undefined; // override framework defaults that may break projectReferences
}
// tsconfig.json with projectReferences
{
  "references": [
    { "path": "../../common/common-a/tsconfig.es.json" },
    { "path": "../../common/common-b/tsconfig.json" }
  ]
}

After these configurations, running the development server triggers a one‑time TypeScript build of the referenced common packages before the main build, allowing the bundler to treat them as real packages. The team reports stable results and plans to further automate reference addition via a custom webpack plugin or enhanced ts‑loader features.

Future work includes addressing other monorepo pain points such as node deployment, yarn.lock hell, and resolution overload, which will be shared in upcoming posts.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

TypeScriptmonorepots-loadercommon packagesProjectReferences
ByteDance Dali Intelligent Technology Team
Written by

ByteDance Dali Intelligent Technology Team

Technical practice sharing from the ByteDance Dali Intelligent Technology Team

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.