How to fix src/index.ts is not under 'rootDir' in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated Dec 10, 2025· 206 views

This TypeScript error occurs when a source file is located outside the directory specified by the rootDir compiler option. TypeScript requires all source files to be within rootDir to maintain a predictable output structure. The fix involves reorganizing files, adjusting tsconfig.json settings, or removing the rootDir constraint.

Quick fix

Fixes TS6059

npx tsc --listFiles | grep -v node_modules
  1. Identify which files are outside rootDir
  2. Move files into the rootDir directory
  3. Exclude files that shouldn't be compiled
  4. Remove or adjust the rootDir option
typescript — error
npx tsc --listFiles | grep -v node_modules
src/index.ts is not under 'rootDir'
shell
npx tsc --listFiles | grep -v node_modules

What this error means

The "file is not under 'rootDir'" error (TS6059) appears when TypeScript encounters a source file that exists outside the directory specified by the rootDir compiler option in tsconfig.json. TypeScript uses rootDir to determine the root of the input file structure, which in turn defines the structure of the output directory. When you set rootDir, TypeScript enforces that all source files must be within that directory or its subdirectories. This ensures that when files are compiled to the outDir, the relative directory structure is preserved and predictable. If a file is outside rootDir, TypeScript cannot determine where to place the compiled output, leading to this error. This error commonly occurs in several scenarios: 1. **Project restructuring**: Files were moved or the project structure changed without updating tsconfig.json 2. **Incorrect configuration**: The rootDir is set too narrowly (e.g., to "src") but some files exist outside that directory 3. **Build scripts**: Configuration files or scripts in the project root try to import from src 4. **Monorepos**: Cross-project imports that violate individual project boundaries 5. **Test files**: Test files located outside the main source directory are accidentally included

Typical symptoms

  • Compilation fails with 'file X is not under rootDir' error message
  • Error code TS6059 appears in compiler output
  • Build succeeds when rootDir is removed from tsconfig.json
  • Only specific files trigger the error while others compile successfully
  • Error appears after moving files or restructuring project directories
  • Configuration files like setupTests.ts in root folder cause build failure
  • Cypress or other test files outside src directory trigger the error

Common causes

  1. rootDir is set to a subdirectory (e.g., 'src') but files exist in parent directory
  2. Configuration files in project root are imported by source files
  3. Test files are located outside the specified rootDir but included in compilation
  4. Files were moved without updating the include/exclude patterns in tsconfig.json
  5. Multiple source directories exist but rootDir points to only one of them
  6. Importing package.json or other project root files from within src directory
  7. Using project references incorrectly in a monorepo setup
  8. The rootDir option is explicitly set when it should be inferred automatically

How to fix "src/index.ts is not under 'rootDir'"

1Identify which files are outside rootDir

Run the TypeScript compiler to see the full error message:

bash
npx tsc --listFiles | grep -v node_modules

The error will tell you exactly which file is problematic:

bash
error TS6059: File '/project/setupTests.ts' is not under 'rootDir' '/project/src'.
'rootDir' is expected to contain all source files.

Make note of:
- The file path that's causing the issue
- The current rootDir value
- Whether this file should be compiled or excluded

2Move files into the rootDir directory

If the files should be compiled, move them into your rootDir:

bash
# Example: Moving a config file into src
mv setupTests.ts src/setupTests.ts

# Update any imports that reference this file
# Before: import './setupTests'
# After:  import './src/setupTests'

For test configuration files:

bash
# Create a test setup directory inside src
mkdir -p src/test
mv setupTests.ts src/test/
mv jest.config.ts src/test/

After moving files, update imports throughout your project and run:

bash
npx tsc
3Exclude files that shouldn't be compiled

If the files outside rootDir don't need to be compiled (like config files), exclude them from compilation:

json
{
  "compilerOptions": {
    "rootDir": "./src",
    "outDir": "./dist"
  },
  "include": ["src/**/*"],
  "exclude": [
    "node_modules",
    "**/*.spec.ts",
    "**/*.test.ts",
    "cypress",
    "setupTests.ts",
    "jest.config.ts"
  ]
}

Common files to exclude:
- Test files: **/*.test.ts, **/*.spec.ts
- Config files: *.config.ts, setupTests.ts
- Test directories: cypress/, e2e/, __tests__/
- Build scripts: scripts/, tools/

4Remove or adjust the rootDir option

If you don't need an explicit rootDir, remove it and let TypeScript infer it automatically:

json
{
  "compilerOptions": {
    // Remove this line:
    // "rootDir": "./src",

    "outDir": "./dist",
    "moduleResolution": "node"
  },
  "include": ["src/**/*"]
}

TypeScript will automatically determine the common root directory of all included files. This is often the simplest solution.

Alternatively, expand rootDir to include all source files:

json
{
  "compilerOptions": {
    "rootDir": ".",        // Project root instead of ./src
    "outDir": "./dist"
  },
  "include": ["src/**/*", "setupTests.ts"]
}

However, this will change your output structure - files from src/ will be in dist/src/ instead of dist/.

5Use separate tsconfig files for different contexts

For projects with multiple compilation contexts (app code + tests + scripts), create separate tsconfig files:

tsconfig.json (base configuration):

json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true
  }
}

tsconfig.build.json (production build):

json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "rootDir": "./src",
    "outDir": "./dist"
  },
  "include": ["src/**/*"],
  "exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"]
}

tsconfig.test.json (for tests):

json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "rootDir": ".",
    "outDir": "./dist-test"
  },
  "include": ["src/**/*", "**/*.test.ts", "setupTests.ts"]
}

Then use the appropriate config:

bash
# Build production code
npx tsc -p tsconfig.build.json

# Type-check tests
npx tsc -p tsconfig.test.json --noEmit
6Configure composite projects for monorepos

If you're in a monorepo with multiple packages, use project references:

packages/app/tsconfig.json:

json
{
  "compilerOptions": {
    "composite": true,
    "rootDir": "./src",
    "outDir": "./dist",
    "declarationDir": "./dist/types"
  },
  "include": ["src/**/*"]
}

packages/shared/tsconfig.json:

json
{
  "compilerOptions": {
    "composite": true,
    "rootDir": "./src",
    "outDir": "./dist"
  },
  "include": ["src/**/*"]
}

Root tsconfig.json:

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

Build all projects:

bash
npx tsc --build

This keeps each package's rootDir separate and properly isolated.

Advanced notes

### How rootDir Affects Output Structure

The rootDir option controls the structure of your compiled output. Consider this project:

bash
project/
├── src/
│   ├── index.ts
│   └── utils/
│       └── helper.ts
└── tsconfig.json

With rootDir: "./src":

json
{
  "compilerOptions": {
    "rootDir": "./src",
    "outDir": "./dist"
  }
}

Output:

bash
dist/
├── index.js
└── utils/
    └── helper.js

Without rootDir (or with rootDir: "."):

json
{
  "compilerOptions": {
    "outDir": "./dist"
  }
}

Output:

bash
dist/
└── src/
    ├── index.js
    └── utils/
        └── helper.js

The rootDir is stripped from the output path, so setting it correctly is important for deployment.

### Why TypeScript Enforces This

TypeScript's strict rootDir enforcement exists for good reason:

1. Predictable output: Every input file has an unambiguous output location
2. Prevent accidental compilation: Configuration files or scripts outside your source tree aren't accidentally compiled
3. Build reproducibility: The same input structure always produces the same output structure

If TypeScript allowed files outside rootDir, it would face two bad options:
- Write output files outside outDir (breaks isolation)
- Flatten the directory structure (loses organization)

### Working with Path Mapping

Path mapping in tsconfig.json doesn't bypass rootDir requirements:

json
{
  "compilerOptions": {
    "rootDir": "./src",
    "baseUrl": ".",
    "paths": {
      "@config/*": ["config/*"]    // config is outside src!
    }
  }
}

If config/ is outside src/, you'll still get the rootDir error even with path mapping. Solutions:

1. Move config into src: src/config/
2. Import config as a package, not source files
3. Use separate tsconfig for config with its own rootDir

### Declaration Files and rootDir

When using declaration: true, the same rootDir constraints apply to .d.ts output:

json
{
  "compilerOptions": {
    "rootDir": "./src",
    "outDir": "./dist",
    "declaration": true,
    "declarationDir": "./types"  // Must match rootDir structure
  }
}

Both JavaScript and declaration files respect the rootDir structure.

### Composite Projects and rootDir

In composite projects (used for project references), rootDir behaves differently:

json
{
  "compilerOptions": {
    "composite": true,
    // rootDir is inferred from the "include" pattern
    "outDir": "./dist"
  },
  "include": ["src/**/*"]
}

With composite: true, TypeScript is more strict about file organization because it builds incremental .tsbuildinfo files.

### Debugging rootDir Issues

See what TypeScript considers the rootDir:

bash
# Show all files TypeScript is processing
npx tsc --listFiles

# Show detailed compiler options
npx tsc --showConfig

The --showConfig output will show the resolved rootDir value, which might be different from what you specified if TypeScript inferred it.

### Avoiding the Problem Entirely

Best practices to prevent this error:

1. Single source directory: Keep all source code in src/, all config in root
2. Explicit include: Use "include": ["src/**/*"] to be explicit
3. Let TypeScript infer: Don't set rootDir unless you need specific output structure
4. Separate configs: Use tsconfig.build.json for build, base tsconfig.json for IDE
5. Test isolation: Keep tests in src/__tests__/ or use separate tsconfig.test.json

Frequently asked questions

What does "TS6059" mean?
json. TypeScript uses rootDir to determine the root of the input file structure, which in turn defines the structure of the output directory. When you set rootDir, TypeScript enforces that all source files must be within that directory or its subdirectories.
How do I fix "TS6059"?
This TypeScript error occurs when a source file is located outside the directory specified by the rootDir compiler option. TypeScript requires all source files to be within rootDir to maintain a predictable output structure. The fix involves reorganizing files, adjusting tsconfig.json settings, or removing the rootDir constraint.
What causes "TS6059"?
rootDir is set to a subdirectory (e.g., 'src') but files exist in parent directory Configuration files in project root are imported by source files Test files are located outside the specified rootDir but included in compilation
Is the "TS6059" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading