Source Maps and Declaration File Output
Introduction
When TypeScript compiles to JavaScript, you often need two companion artifacts: source maps for debugging and declaration files (.d.ts) for consumers of your library. This chapter explains what they are, which tsconfig flags emit them, and how they fit into publish and debug workflows.
Prerequisites
What Happens During tsc
src/index.ts ──► dist/index.js
├► dist/index.js.map (optional source map)
└► dist/index.d.ts (optional declaration)Runtime executes .js. Editors and debuggers use .map to map stack traces back to .ts. Other TypeScript projects use .d.ts for types without your source.
sourceMap
{
"compilerOptions": {
"sourceMap": true,
"outDir": "dist",
"rootDir": "src"
}
}Emitted dist/index.js ends with:
//# sourceMappingURL=index.js.mapUses:
- Breakpoints in VS Code on
.tswhile running.js - Readable stack traces in Node and browsers
- Error monitoring tools showing original lines
inlineSourceMap and inlineSources
| Option | Output |
|---|---|
sourceMap: true | Separate .js.map file |
inlineSourceMap: true | Map embedded in .js (no separate file) |
inlineSources: true | Embed TS source inside map (larger) |
Libraries published to npm usually use separate sourceMap files or omit maps in production builds.
declaration and declarationMap
For libraries consumed by other TypeScript projects:
{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"outDir": "dist",
"rootDir": "src"
}
}Produces:
dist/
index.js
index.d.ts
index.d.ts.mapCode explanation:
declarationemits type-only descriptions of exportsdeclarationMaplinks.d.tsback to.tsfor “Go to Definition” into source when users install your package
Example emitted declaration
Source src/math.ts:
export function add(a: number, b: number): number {
return a + b;
}Emitted dist/math.d.ts (conceptually):
export declare function add(a: number, b: number): number;No function bodies—types only.
package.json for Libraries
Point consumers at types and JS:
Publish only dist/ (plus README), not raw src/, unless you also ship source for maps.
noEmit vs Emit Pipelines
| Setup | Who emits JS | Who emits types |
|---|---|---|
tsc only | tsc | tsc with declaration |
| Vite / esbuild | Bundler | tsc --emitDeclarationOnly or vite-plugin-dts |
| Type-check in CI | Bundler | Separate tsc -p tsconfig.types.json |
Frontend app (Vite) often:
{
"compilerOptions": {
"noEmit": true,
"sourceMap": true
}
}Bundler generates JS + maps; tsc only checks types.
Library (dual output) pattern:
{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "dist"
}
}Debugging in Node with Source Maps
Node 16+ loads source maps when enabled:
node --enable-source-maps dist/index.jsOr set in environment / NODE_OPTIONS for development.
VS Code launch.json for TypeScript projects often points at dist/*.js with sourceMaps: true and outFiles matching dist.
What Not to Commit
| Artifact | Typical git policy |
|---|---|
src/ | Commit |
dist/ | Ignore for apps; publish via CI for libs |
*.js.map | Ignore locally; optional on npm for libs |
*.d.ts in dist | Published to npm, not always in app repo |
Common Issues
| Problem | Cause | Fix |
|---|---|---|
Breakpoints skip .ts | Maps missing or wrong outDir | Enable sourceMap; check paths |
Consumer sees any | No .d.ts published | declaration: true; set types in package.json |
| Duplicate type errors | Publishing .ts and .d.ts conflict | Export only dist types |
| Huge npm package | inlineSources + maps | Exclude maps from production publish |
FAQ
Do I need declaration files for apps?
Usually no—only the app team runs tsc. Libraries need .d.ts for npm consumers.
sourceMap in production?
Helps debug production issues; some teams upload maps to monitoring tools privately instead of shipping to browsers.
declarationMap required?
Optional but improves DX for library users stepping into your source.
Can I generate .d.ts without .js?
tsc --emitDeclarationOnly with noEmit: false and declaration: true—common beside bundlers.
.d.ts hand-written?
Yes for declare module and ambient types—next chapters.
composite and incremental?
Project references use composite for faster builds—monorepo topic; pairs with declaration: true.