Glossary

Source map

Source map is a JSON file that maps positions in generated code, such as minified JavaScript, back to positions in the original source files. Browser DevTools and Node.js use it to show your real file names and line numbers while debugging. The format is version 3 and is standardized as ECMA-426. Generated files point to their map with a comment ending in sourceMappingURL= followed by the map's file name.

How it works

A source map has these top-level fields:

  • version: always the integer 3. A reader may reject any other value.
  • sources: list of original file URLs, relative to sourceRoot if one is set.
  • sourcesContent: optional list of the original file contents, in the same order as sources. Entries can be null.
  • names: optional list of original identifiers that the mappings can refer to.
  • mappings: one string holding all the position data.
  • file, sourceRoot, ignoreList: optional. ignoreList holds indices of third-party files, such as framework code, that debuggers should skip.

In mappings, a semicolon ends a generated line and a comma separates segments within a line. Each segment is one, four or five numbers, each written as a base64 VLQ, a variable-length quantity where the sixth bit of each base64 digit is a continuation flag. A segment has 1 field (generated column only), 4 fields (generated column, source index, original line, original column) or 5 fields (the same plus a names index). Each value is a delta from that field's previous value. The generated column restarts at 0 on each new line, while the other four fields carry over across lines. Lines and columns are zero-based.

A generated file links to its map with //# sourceMappingURL=app.js.map on its last line. CSS uses /# sourceMappingURL=app.css.map /. A server can also send the map's URL in a SourceMap HTTP response header; the older X-SourceMap name is deprecated.

This example minifies a four-line file with esbuild 0.28.2, then decodes the first line of mappings with a short Node script:

$ esbuild src/app.js --minify --sourcemap --outfile=out.js
$ cat out.js
function greet(e){return"Hello, "+e}console.log(greet("map"));
//# sourceMappingURL=out.js.map
$ node -e '...'      # print keys of out.js.map, then decode each segment of line 1
version, sources, sourcesContent, mappings, names
AAAA     [0,0,0,0]
SAAS     [9,0,0,9]
MAAMA    [6,0,0,6,0]
EAAM     [2,0,0,6]
CACnB    [1,0,1,-19]

The third segment has five numbers, and its last one points at index 0 of names, which is name. The fifth segment moves one generated column and one original line down, then back 19 columns.

How do I see original line numbers in Node.js stack traces?

Start Node with --enable-source-maps. It was added in v12.12.0 and is no longer experimental since v15.11.0 and v14.18.0. Without it, a minified file reports the position in the generated code. With it, the same error reports the original file (output filtered to two lines):

$ node b.js 2>&1 | grep -E '^Error|at boom' | sed "s|$PWD/||"
Error: bad x
    at boom (b.js:1:24)
$ node --enable-source-maps b.js 2>&1 | grep -E '^Error|at boom' | sed "s|$PWD/||"
Error: bad x
    at boom (src/boom.js:2:9)

Common pitfalls

  • Shipping sourcesContent to production: the map can contain your complete original source, and anyone who can fetch the .map file can read it. Upload maps to your error tracker instead of publishing them, or restrict access.
  • Mismatched map and bundle: a map only works for the exact generated file it was built with. After a rebuild, old maps give wrong lines.
  • Comment not on the last line: extractors look for the annotation at the end of the file. Appending code or a minifier pass after it can break the link.
  • JSON parse failure: some servers prefix maps with )]}' as an XSSI guard. The spec tells consumers to strip that prefix up to the first newline, but a script that calls JSON.parse directly on the response will fail.
  • Overriding stack formatting: the Node documentation warns that replacing Error.prepareStackTrace can stop --enable-source-maps from working.
  • Wrong columns for non-ASCII code: for JavaScript, columns are counted in UTF-16 code units, not bytes or code points.

Related terms

  • Minifier — the most common tool that creates the need for a source map.
  • AST — compilers and bundlers build a syntax tree while they track original positions.
  • JSON — the container format of a source map file.
  • Base64 — the alphabet used by the VLQ digits in the mappings string.
  • HTTP — carries the SourceMap response header.

See also

  • Term: Minifier — the transform whose output a source map reverses