Skip to content
Latchkey

TypeScript "TS6059: not under 'rootDir'" - Fix Project Refs in CI

A file you compile imports source from outside the configured rootDir. rootDir defines the root of the input set; reaching across to another package's src/ (common in monorepos) violates it, and tsc refuses with TS6059.

What this error means

Type-checking fails with error TS6059: '<file>' is not under 'rootDir' '<dir>'. 'rootDir' is expected to contain all source files. It names the cross-boundary file.

tsc output
error TS6059: File '/repo/packages/shared/src/types.ts' is not under 'rootDir'
'/repo/packages/web/src'. 'rootDir' is expected to contain all source files.
  The file is in the program because:
    Imported via '../../shared/src/types' from file 'src/App.tsx'

Diagnose it: which tsconfig and which compiler?

A TypeScript error that appears only in CI usually means the runner is compiling with a different config or a different compiler version than your editor. Your editor uses the workspace TypeScript and the nearest tsconfig.json; CI uses whatever the lockfile resolved and whatever config the build script names.

Terminal
# what CI will actually use
npx tsc --version
npx tsc --showConfig | head -40

# which files are in the program (a missing include is a common cause)
npx tsc --listFiles | wc -l

# type-check only, no emit, same as most CI gates
npx tsc --noEmit

Common causes

Importing another package's source across rootDir

In a monorepo, web imports shared/src/... directly. Since shared is outside web's rootDir, tsc treats it as an out-of-root input and errors.

rootDir narrower than the actual input set

An explicit rootDir (e.g. src) that does not contain every file the program pulls in - including referenced files outside it - triggers TS6059.

How to fix it

Use project references for cross-package imports

Reference the other package as a built project and import its emitted types, not its raw source.

tsconfig.json
// packages/web/tsconfig.json
{
  "compilerOptions": { "composite": true },
  "references": [{ "path": "../shared" }]
}

Widen rootDir or import the built package

  1. Either set rootDir to a common ancestor that contains all inputs,
  2. or import the dependency by its package name (resolved to its dist/types), not a relative ../../pkg/src path.
  3. Avoid deep relative imports across package boundaries.

Pin the compiler so unrelated updates cannot break the gate

TypeScript adds errors in minor releases. An unpinned compiler turns a routine dependency update into a red build on code nobody touched, which is the most common false alarm in a TypeScript CI pipeline.

package.json
// package.json
{
  "devDependencies": {
    "typescript": "5.6.3"   // exact, not ^5.6.3
  }
}

How to prevent it

  • Use TypeScript project references in monorepos.
  • Import sibling packages by name, not by relative paths into their src.
  • Keep rootDir consistent with the real input set.

Frequently asked questions

What causes TypeScript "TS6059: not under 'rootDir'"?
There are 2 common causes: importing another package's source across rootdir and rootdir narrower than the actual input set. In a monorepo, web imports shared/src/...
How do I fix TypeScript "TS6059: not under 'rootDir'"?
There are 2 fixes depending on which cause you have: use project references for cross-package imports and widen rootdir or import the built package. Work through them in order, since the first is the most common.
What does TypeScript "TS6059: not under 'rootDir'" actually mean?
Type-checking fails with error TS6059: '<file>' is not under 'rootDir' '<dir>'.
How do I stop TypeScript "TS6059: not under 'rootDir'" happening again?
Use TypeScript project references in monorepos. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card