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

text
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

json
{
  "compilerOptions": {
    "sourceMap": true,
    "outDir": "dist",
    "rootDir": "src"
  }
}

Emitted dist/index.js ends with:

javascript
//# sourceMappingURL=index.js.map

Uses:

  • Breakpoints in VS Code on .ts while running .js
  • Readable stack traces in Node and browsers
  • Error monitoring tools showing original lines

inlineSourceMap and inlineSources

OptionOutput
sourceMap: trueSeparate .js.map file
inlineSourceMap: trueMap embedded in .js (no separate file)
inlineSources: trueEmbed 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:

json
{
  "compilerOptions": {
    "declaration": true,
    "declarationMap": true,
    "outDir": "dist",
    "rootDir": "src"
  }
}

Produces:

text
dist/
  index.js
  index.d.ts
  index.d.ts.map

Code explanation:

  • declaration emits type-only descriptions of exports
  • declarationMap links .d.ts back to .ts for “Go to Definition” into source when users install your package

Example emitted declaration

Source src/math.ts:

typescript
export function add(a: number, b: number): number {
  return a + b;
}

Emitted dist/math.d.ts (conceptually):

typescript
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

SetupWho emits JSWho emits types
tsc onlytsctsc with declaration
Vite / esbuildBundlertsc --emitDeclarationOnly or vite-plugin-dts
Type-check in CIBundlerSeparate tsc -p tsconfig.types.json

Frontend app (Vite) often:

json
{
  "compilerOptions": {
    "noEmit": true,
    "sourceMap": true
  }
}

Bundler generates JS + maps; tsc only checks types.

Library (dual output) pattern:

json
{
  "compilerOptions": {
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "outDir": "dist"
  }
}

Debugging in Node with Source Maps

Node 16+ loads source maps when enabled:

bash
node --enable-source-maps dist/index.js

Or 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

ArtifactTypical git policy
src/Commit
dist/Ignore for apps; publish via CI for libs
*.js.mapIgnore locally; optional on npm for libs
*.d.ts in distPublished to npm, not always in app repo

Common Issues

ProblemCauseFix
Breakpoints skip .tsMaps missing or wrong outDirEnable sourceMap; check paths
Consumer sees anyNo .d.ts publisheddeclaration: true; set types in package.json
Duplicate type errorsPublishing .ts and .d.ts conflictExport only dist types
Huge npm packageinlineSources + mapsExclude 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.