Module Resolution Overview
Module resolution is the process of determining which file animport statement refers to. TypeScript’s module resolution logic is implemented in src/compiler/moduleNameResolver.ts (181KB).
Module resolution is separate from type checking and happens during the program creation phase.
Resolution Strategies
TypeScript supports multiple module resolution strategies:ModuleResolutionKind
Classic
Legacy resolution strategy. Rarely used in modern projects.
Node10 (NodeJs)
Mimics Node.js CommonJS resolution. Most common for older projects.
Node16
Supports both ESM and CommonJS with package.json “exports”.
NodeNext
Latest Node.js resolution. Tracks Node.js updates.
Bundler
Optimized for bundlers like webpack, esbuild. Relaxed rules.
Node Resolution Algorithm
Node10 Resolution (Classic Node.js)
For relative imports likeimport { x } from "./module":
For non-relative imports like
import { x } from "library":
Node16/NodeNext Resolution
These modes support package.jsonexports field:
Node16/NodeNext enforce that ESM imports must include file extensions:
Resolution Features
TypeScript extends Node’s resolution with additional features:Path Mapping
Configure custom module paths intsconfig.json:
Base URL
Set a base directory for non-relative imports:Root Dirs
Treat multiple directories as a single virtual directory:Module Resolution State
The resolver maintains state during resolution:Resolution Tracing
Enable detailed resolution logging:Resolution Caching
Module resolution results are cached for performance:The cache is invalidated when:
- Compiler options change
- Files are added/removed
- package.json files change
Resolution Result
Successful resolution returns:Extension Resolution
The resolver tries different file extensions:Extension Priority
- Standard Import
- Type-Only Import
- JSON Import
module.tsmodule.tsxmodule.d.tsmodule/index.tsmodule/index.tsxmodule/index.d.ts
Package.json Support
TypeScript respects several package.json fields:Standard Fields
types
Primary field for TypeScript declarations
typings
Alternative to “types” (older packages)
main
Fallback entry point
Exports Field (Node16+)
Type Versioning
Resolution Modes
Import vs Require Resolution
Triple-Slash Directives
Troubleshooting Resolution
Module Not Found
Module Not Found
Problem:
Cannot find module './utils' or its corresponding type declarations.Solutions:- Verify the file exists
- Check file extension requirements (Node16+)
- Enable
traceResolutionto see lookup paths - Check
baseUrlandpathsconfiguration
Wrong File Resolved
Wrong File Resolved
Problem: TypeScript resolves to an unexpected file.Solutions:
- Clear the module resolution cache
- Check for multiple
node_modulesdirectories - Verify
pathsmapping order - Review package.json “exports” field
Type Declarations Missing
Type Declarations Missing
Problem: Library found but no type declarations.Solutions:
- Install
@types/librarypackage - Check package.json “types” field
- Add ambient declarations (
.d.tsfile) - Use
skipLibCheckas temporary workaround
Package.json Exports Not Working
Package.json Exports Not Working
Problem: Exports field ignored.Solutions:
- Use
Node16orNodeNextmodule resolution - Update TypeScript to 4.7+
- Verify exports field syntax
- Check for “types” condition in exports
Best Practices
Use Modern Resolution
Prefer
Node16 or NodeNext for new projects to support package.json exports.Avoid Deep Relative Imports
Use path mapping to simplify imports:
Enable Resolution Tracing
Use
traceResolution during debugging:Related Topics
Compiler Overview
Learn about the full compilation pipeline
Emit
Understand JavaScript generation