How to fix src/index.ts is not under 'rootDir' in TypeScript
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- Identify which files are outside rootDir
- Move files into the rootDir directory
- Exclude files that shouldn't be compiled
- Remove or adjust the rootDir option
npx tsc --listFiles | grep -v node_modulessrc/index.ts is not under 'rootDir'
npx tsc --listFiles | grep -v node_modulesWhat 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
- 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
- Files were moved without updating the include/exclude patterns in tsconfig.json
- Multiple source directories exist but rootDir points to only one of them
- Importing package.json or other project root files from within src directory
- Using project references incorrectly in a monorepo setup
- The rootDir option is explicitly set when it should be inferred automatically
How to fix "src/index.ts is not under 'rootDir'"
Run the TypeScript compiler to see the full error message:
npx tsc --listFiles | grep -v node_modulesThe error will tell you exactly which file is problematic:
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
If the files should be compiled, move them into your rootDir:
# 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:
# 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:
npx tscIf the files outside rootDir don't need to be compiled (like config files), exclude them from compilation:
{
"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/
If you don't need an explicit rootDir, remove it and let TypeScript infer it automatically:
{
"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:
{
"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/.
For projects with multiple compilation contexts (app code + tests + scripts), create separate tsconfig files:
tsconfig.json (base configuration):
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true
}
}tsconfig.build.json (production build):
{
"extends": "./tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src/**/*"],
"exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"]
}tsconfig.test.json (for tests):
{
"extends": "./tsconfig.json",
"compilerOptions": {
"rootDir": ".",
"outDir": "./dist-test"
},
"include": ["src/**/*", "**/*.test.ts", "setupTests.ts"]
}Then use the appropriate config:
# Build production code
npx tsc -p tsconfig.build.json
# Type-check tests
npx tsc -p tsconfig.test.json --noEmitIf you're in a monorepo with multiple packages, use project references:
packages/app/tsconfig.json:
{
"compilerOptions": {
"composite": true,
"rootDir": "./src",
"outDir": "./dist",
"declarationDir": "./dist/types"
},
"include": ["src/**/*"]
}packages/shared/tsconfig.json:
{
"compilerOptions": {
"composite": true,
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src/**/*"]
}Root tsconfig.json:
{
"files": [],
"references": [
{ "path": "./packages/app" },
{ "path": "./packages/shared" }
]
}Build all projects:
npx tsc --buildThis 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:
project/
├── src/
│ ├── index.ts
│ └── utils/
│ └── helper.ts
└── tsconfig.jsonWith rootDir: "./src":
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
}
}Output:
dist/
├── index.js
└── utils/
└── helper.jsWithout rootDir (or with rootDir: "."):
{
"compilerOptions": {
"outDir": "./dist"
}
}Output:
dist/
└── src/
├── index.js
└── utils/
└── helper.jsThe 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:
{
"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:
{
"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:
{
"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:
# Show all files TypeScript is processing
npx tsc --listFiles
# Show detailed compiler options
npx tsc --showConfigThe --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
- 📚TypeScript Official Documentation
- 📖TypeScript TSConfig Reference - rootDir(Official Docs)
- 📖TypeScript TSConfig Reference(Official Docs)
- 🐙
- 🐙