This TypeScript error occurs when you try to use incremental compilation features without enabling the required configuration options. It typically happens when using TypeScript's project references or build mode without proper tsconfig.json settings for incremental builds, preventing faster compilation through cached results.
The 'Incremental builds require incremental or composite option' error indicates that TypeScript's incremental compilation system cannot function because the necessary configuration options are missing. TypeScript's incremental build feature saves compilation information to .tsbuildinfo files, allowing faster subsequent builds by reusing previous compilation results. This feature requires either the 'incremental' option to be explicitly set to true, or the 'composite' option to be enabled (which automatically enables incremental builds). The error prevents TypeScript from creating or using the .tsbuildinfo files needed for efficient rebuilds in large projects.
Add or update the 'incremental' option in your tsconfig.json file:
{
"compilerOptions": {
"incremental": true,
"target": "es2020",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"]
}This tells TypeScript to save build information to .tsbuildinfo files for faster subsequent compilations. The cache file will be created in your output directory (specified by outDir).
If you're using TypeScript project references, enable the 'composite' option:
{
"compilerOptions": {
"composite": true,
"incremental": true,
"target": "es2020",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src"
},
"references": [
{ "path": "../shared" },
{ "path": "../utils" }
]
}The 'composite' option automatically enables incremental builds and is required for project references to work correctly. Composite mode enables proper build ordering between projects and cross-project type checking.
After updating your configuration, clean any existing build artifacts and rebuild:
# Delete existing build artifacts
rm -rf dist build
rm -f *.tsbuildinfo
# Rebuild with clean cache
npx tsc --build --clean
npx tsc --build
# Alternative: Use force flag
npx tsc --build --forceThis ensures TypeScript starts fresh with the new configuration and generates proper .tsbuildinfo files.
For better control over build artifacts, specify where .tsbuildinfo files should be stored:
{
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": "./.cache/.tsbuildinfo",
"target": "es2020",
"module": "commonjs",
"outDir": "./dist"
}
}This keeps build metadata separate from your source code and output directories. Consider adding .tsbuildinfo to .gitignore to avoid merge conflicts.
Ensure you're using a compatible TypeScript version (3.4 or later for incremental builds):
# Check TypeScript version
npx tsc --version
# Update if needed
npm install typescript@latest --save-dev
# Check installed version
npm list typescriptIncremental builds were introduced in TypeScript 3.4. Some features may require newer versions for optimal performance. TypeScript 4.0+ offers improved cache invalidation and performance.
If using build tools like webpack, vite, or esbuild, ensure they're configured correctly:
Webpack with ts-loader:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /.tsx?$/,
use: {
loader: 'ts-loader',
options: {
configFile: 'tsconfig.json'
}
}
}
]
}
};Vite with TypeScript:
// vite.config.ts
import { defineConfig } from 'vite';
export default defineConfig({
esbuild: {
tsconfigRaw: {
compilerOptions: {
incremental: true
}
}
}
});Ensure your tsconfig.json has 'incremental': true and the build tool can read it.
## Understanding .tsbuildinfo Files
.tsbuildinfo files contain metadata about your TypeScript project's compilation state, including:
- Which files were compiled
- Their dependencies
- Compiler options used
- Output file hashes
These files are safe to delete and will be regenerated on the next build. They contain no runtime code.
## Performance Considerations
Incremental builds can significantly reduce compilation times for large projects:
- First build: Normal speed (creates .tsbuildinfo)
- Subsequent builds: 30-70% faster (uses .tsbuildinfo)
However, the performance gain depends on:
- Project size (larger projects benefit more)
- Frequency of changes (small, incremental changes benefit most)
- Disk I/O speed (SSDs help with .tsbuildinfo file access)
## Common Pitfalls
1. Git conflicts: .tsbuildinfo files can cause merge conflicts. Consider adding them to .gitignore:
*.tsbuildinfo2. CI/CD environments: Ensure .tsbuildinfo files are preserved between builds or disabled in CI:
{
"compilerOptions": {
"incremental": false // Disable for CI to ensure clean builds
}
}3. Monorepos: In monorepos with multiple TypeScript projects, each project needs its own tsconfig.json with appropriate incremental/composite settings.
4. File watching: For development servers, ensure file watcher limits are sufficient:
# Increase file watcher limits (Linux/macOS)
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p## Integration with Testing Frameworks
Jest with ts-jest: Ensure ts-jest uses your tsconfig.json:
// jest.config.js
module.exports = {
preset: 'ts-jest',
globals: {
'ts-jest': {
tsconfig: 'tsconfig.json'
}
}
};Vitest: Uses Vite's TypeScript configuration automatically.
Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript
Type narrowing from typeof check produces 'never'
How to fix "Type narrowing produces never" in TypeScript
Type parameter 'T' has conflicting constraints
How to fix "Type parameter has conflicting constraints" in TypeScript