How to fix Project 'X' cannot reference itself in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated Dec 11, 2025· 115 views

This TypeScript error occurs when a project references itself in its own tsconfig.json file, creating a circular dependency. This typically happens in monorepos or project reference configurations where a project accidentally includes itself in its references array. The fix involves removing the self-reference from the references array.

Quick fix

Fixes Project 'X' cannot reference itself

{
  "compilerOptions": {
    "composite": true,
    "outDir": "./dist"
  },
  "references": [
    {
      "path": "../shared"  // ✓ Correct - references another project
    },
    {
      "path": "."          // ✗ WRONG - references itself!
    },
    {
      "path": "./"         // ✗ WRONG - also references itself
    }
  ]
}
  1. Check your tsconfig.json references array
  2. Verify project boundaries in monorepos
  3. Use path resolution helpers for complex structures
  4. Check for indirect self-references through symlinks
typescript — error
{
"compilerOptions": {
"composite": true,
"outDir": "./dist"
},
"references": [
{
"path": "../shared" // ✓ Correct - references another project
},
{
"path": "." // ✗ WRONG - references itself!
},
{
"path": "./" // ✗ WRONG - also references itself
}
]
}
Project 'X' cannot reference itself

What this error means

The "Project cannot reference itself" error appears when TypeScript's project references feature detects a circular dependency where a project references itself. This is invalid because it would create an infinite compilation loop. TypeScript project references allow you to structure large codebases into smaller, interdependent projects that can be built independently. Each project has its own tsconfig.json file and can reference other projects. However, a project cannot reference itself because: 1. **Circular dependency**: A project building itself would need to wait for itself to finish building 2. **Infinite recursion**: The compiler would get stuck in an endless loop trying to resolve dependencies 3. **Build system confusion**: Tools like tsc --build wouldn't know where to start This error commonly occurs in: - Monorepos with many interconnected packages - Complex build configurations with nested project structures - Copy-paste errors when setting up project references - Automated tooling that incorrectly generates tsconfig.json files

Typical symptoms

  • TypeScript compilation fails with 'Project cannot reference itself' error
  • tsc --build command fails with circular dependency error
  • IDE shows errors in tsconfig.json file
  • Build process hangs or crashes when using project references
  • Error occurs specifically when using the references array in tsconfig.json
  • Project builds successfully when removing the self-reference

Common causes

  1. Accidentally including the current project in its own references array
  2. Copy-pasting tsconfig.json files between projects without updating references
  3. Automated tools or scripts incorrectly generating project references
  4. Symlinks or aliases causing the project to reference itself indirectly
  5. Relative path calculations that resolve to the current project directory
  6. Monorepo tooling misconfiguring project boundaries
  7. Nested tsconfig.json files where a parent references a child that includes the parent

How to fix "Project 'X' cannot reference itself"

1Check your tsconfig.json references array

Open your tsconfig.json file and examine the "references" array:

json
{
  "compilerOptions": {
    "composite": true,
    "outDir": "./dist"
  },
  "references": [
    {
      "path": "../shared"  // ✓ Correct - references another project
    },
    {
      "path": "."          // ✗ WRONG - references itself!
    },
    {
      "path": "./"         // ✗ WRONG - also references itself
    }
  ]
}

Remove any entries that point to the current directory (".", "./", or the project's own path).

2Verify project boundaries in monorepos

In monorepos, ensure each package has clear boundaries:

json
// packages/app/tsconfig.json
{
  "references": [
    {
      "path": "../shared"  // ✓ References sibling package
    },
    {
      "path": "../utils"   // ✓ References another sibling
    }
    // NO self-reference here
  ]
}

// packages/shared/tsconfig.json
{
  "references": [
    // Can reference other packages, but not itself
    {
      "path": "../utils"   // ✓ OK
    }
  ]
}

Use absolute or relative paths that clearly point to other projects, never to the current one.

3Use path resolution helpers for complex structures

For complex project structures, use helper functions or variables:

json
// Using tsconfig-paths or similar tools
{
  "extends": "../../tsconfig.base.json",
  "references": [
    {
      "path": "<workspaceRoot>/packages/shared"
    },
    {
      "path": "<workspaceRoot>/packages/utils"
    }
  ]
}

// Or with explicit relative paths:
{
  "references": [
    {
      "path": "../../packages/shared"  // Clear relative path
    }
  ]
}

Avoid dynamic path generation that might accidentally resolve to the current project.

4Check for indirect self-references through symlinks

Symlinks can create indirect self-references:

bash
# Check for symlinks in your project
ls -la node_modules/

# If using npm/yarn workspaces, check for linked packages
npm ls --link

# Remove problematic symlinks if found
rm -f node_modules/current-package

Also check package.json for unusual configurations:

json
{
  "name": "my-package",
  "dependencies": {
    "my-package": "file:."  // ✗ Self-reference in dependencies!
  }
}

Fix by removing self-dependencies.

5Validate with tsc --build --verbose

Use TypeScript's build mode with verbose output to debug:

bash
# Run build with verbose output
npx tsc --build --verbose

# Or for specific tsconfig
npx tsc --project tsconfig.json --build --verbose

# Output will show:
# Project 'packages/app' references:
#   - packages/shared
#   - packages/app  <-- This is the problem!

The verbose output clearly shows which projects reference which others, making self-references obvious.

6Clean and rebuild the project

After fixing the references, clean and rebuild:

bash
# Clean build outputs
npx tsc --build --clean

# Or manually remove output directories
rm -rf dist
rm -rf build
rm -rf .tsbuildinfo

# Rebuild from scratch
npx tsc --build

# For incremental builds
npx tsc --build --incremental

If using a monorepo tool:

bash
# With npm workspaces
npm run build --workspaces

# With yarn workspaces
yarn workspaces foreach run build

# With pnpm
pnpm -r run build

Advanced notes

### Understanding TypeScript Project References

Project references are a TypeScript feature for structuring large codebases. Key concepts:

1. Composite Projects: Must have "composite": true in tsconfig.json
2. Reference Resolution: TypeScript follows references to build dependencies first
3. Build Outputs: Each project produces .tsbuildinfo files for incremental builds

### Common Monorepo Patterns

Lerna/Yarn Workspaces:

json
// packages/app/tsconfig.json
{
  "references": [
    { "path": "../shared" },
    { "path": "../utils" }
  ]
}

Nx Workspace:

json
{
  "extends": "../../tsconfig.base.json",
  "references": [
    { "path": "../shared" }
  ]
}

Turborepo:

json
{
  "references": [
    { "path": "../packages/shared" }
  ]
}

### Debugging Complex Reference Chains

Use tsc --build --dry --verbose to see the build plan without executing:

bash
npx tsc --build --dry --verbose

This shows the build order and reveals circular dependencies.

### Preventing Future Issues

1. Use tsconfig schema validation in IDEs
2. Add linting rules for tsconfig.json
3. Template tsconfig files for new projects
4. Automated validation in CI/CD pipelines

### Alternative: Solution References

For very complex dependency graphs, consider Solution References (tsconfig.solution.json):

json
// tsconfig.solution.json
{
  "files": [],
  "references": [
    { "path": "./packages/core" },
    { "path": "./packages/utils" },
    { "path": "./packages/app" }
  ]
}

Then build with: tsc --build tsconfig.solution.json

Frequently asked questions

What does "Project 'X' cannot reference itself" mean?
The "Project cannot reference itself" error appears when TypeScript's project references feature detects a circular dependency where a project references itself. This is invalid because it would create an infinite compilation loop. TypeScript project references allow you to structure large codebases into smaller, interdependent projects that can be built independently.
How do I fix "Project 'X' cannot reference itself"?
This TypeScript error occurs when a project references itself in its own tsconfig.json file, creating a circular dependency. This typically happens in monorepos or project reference configurations where a project accidentally includes itself in its references array. The fix involves removing the self-reference from the references array.
What causes "Project 'X' cannot reference itself"?
Accidentally including the current project in its own references array Copy-pasting tsconfig.json files between projects without updating references Automated tools or scripts incorrectly generating project references
Is the "Project 'X' cannot reference itself" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading