NX-generated tsconfig uses deprecated baseUrl causing incompatibility with modern bundlers
Current Behavior
NX generates tsconfig.base.json with baseUrl: "." and non-relative paths in the paths mapping:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@myorg/lib1": ["packages/lib1/src"],
"@myorg/lib2": ["packages/lib2/src"]
}
}
}
This configuration causes failures with modern TypeScript tooling that follows newer TypeScript standards, specifically:
- tsdown with
tsgo option (TypeScript isolated declarations)
- Potentially other bundlers using TypeScript's isolated declarations feature
Error Messages
When using modern bundlers with this configuration:
TS5090: Non-relative paths are not allowed. Did you forget a leading './'?
TS5102: Option 'baseUrl' has been removed. Please remove it from your configuration.
Use '"paths": {"*": ["../../*"]}' instead.
Expected Behavior
NX should generate tsconfig with relative paths that are compatible with modern TypeScript tooling:
{
"compilerOptions": {
"paths": {
"@myorg/lib1": ["./packages/lib1/src"],
"@myorg/lib2": ["./packages/lib2/src"]
}
}
}
Steps to Reproduce
- Create a new NX workspace with TypeScript libraries
- Install and configure
tsdown for building a library
- Enable DTS generation (auto-detected or explicit)
- Run build
Example tsdown.config.ts:
import { defineConfig } from 'tsdown';
export default defineConfig({
sourcemap: true,
tsconfig: 'tsconfig.lib.json',
skipNodeModulesBundle: true
// dts is auto-detected from package.json
});
Build fails with:
ERROR: Build failed with errors:
[UNRESOLVED_IMPORT] Error: Could not resolve './types.js' in ../types/src/index.d.ts
Workaround
Manually update tsconfig.base.json:
{
"compilerOptions": {
- "baseUrl": ".",
"paths": {
- "@myorg/lib1": ["packages/lib1/src"],
- "@myorg/lib2": ["packages/lib2/src"]
+ "@myorg/lib1": ["./packages/lib1/src"],
+ "@myorg/lib2": ["./packages/lib2/src"]
}
}
}
After this change, builds work correctly with modern bundlers.
Context
Why This Matters
- TypeScript Evolution: The TypeScript team has deprecated
baseUrl in favor of relative paths
- Modern Tooling: Tools using TypeScript's isolated declarations (like tsdown's tsgo) require the newer format
- Future Compatibility: As more tools adopt isolated declarations, this will become a broader issue
Related Issues
Proposed Solution
- Update NX generators to create tsconfig files with relative paths (using
./ prefix) and without baseUrl
- Provide migration for existing workspaces (perhaps an
nx migrate command)
- Update documentation to reflect this change and explain the reasoning
- Add warning when detecting the old format to guide users to update
Environment
- NX Version: (affects all versions using current tsconfig template)
- Node Version: v20+
- Package Manager: npm/pnpm/yarn
- Operating System: All platforms
- Affected Bundlers: tsdown (confirmed), potentially others using isolated declarations
Additional Information
This is not just a tsdown-specific issue. As TypeScript evolves and more tools adopt isolated declarations and modern TypeScript features, the current NX-generated tsconfig format will cause increasing compatibility problems.
The fix is straightforward (add ./ prefix to paths, remove baseUrl) and maintains backward compatibility with existing TypeScript compilation while enabling compatibility with modern tooling.
NX-generated tsconfig uses deprecated
baseUrlcausing incompatibility with modern bundlersCurrent Behavior
NX generates
tsconfig.base.jsonwithbaseUrl: "."and non-relative paths in thepathsmapping:{ "compilerOptions": { "baseUrl": ".", "paths": { "@myorg/lib1": ["packages/lib1/src"], "@myorg/lib2": ["packages/lib2/src"] } } }This configuration causes failures with modern TypeScript tooling that follows newer TypeScript standards, specifically:
tsgooption (TypeScript isolated declarations)Error Messages
When using modern bundlers with this configuration:
Expected Behavior
NX should generate tsconfig with relative paths that are compatible with modern TypeScript tooling:
{ "compilerOptions": { "paths": { "@myorg/lib1": ["./packages/lib1/src"], "@myorg/lib2": ["./packages/lib2/src"] } } }Steps to Reproduce
tsdownfor building a libraryExample tsdown.config.ts:
Build fails with:
Workaround
Manually update
tsconfig.base.json:{ "compilerOptions": { - "baseUrl": ".", "paths": { - "@myorg/lib1": ["packages/lib1/src"], - "@myorg/lib2": ["packages/lib2/src"] + "@myorg/lib1": ["./packages/lib1/src"], + "@myorg/lib2": ["./packages/lib2/src"] } } }After this change, builds work correctly with modern bundlers.
Context
Why This Matters
baseUrlin favor of relative pathsRelated Issues
Proposed Solution
./prefix) and withoutbaseUrlnx migratecommand)Environment
Additional Information
This is not just a tsdown-specific issue. As TypeScript evolves and more tools adopt isolated declarations and modern TypeScript features, the current NX-generated tsconfig format will cause increasing compatibility problems.
The fix is straightforward (add
./prefix to paths, removebaseUrl) and maintains backward compatibility with existing TypeScript compilation while enabling compatibility with modern tooling.