File types · Explainer

The source map file (.map, .js.map, .css.map)

A source map is a small JSON file that links compiled, minified or bundled code back to the original source files it was made from, so developer tools can show and debug the code you actually wrote. This guide explains what's inside one, how its mappings are encoded, how browsers find it, the privacy risk of publishing it, and has free sample source map files to download for testing.

At a glance

Full name
Source map (Source Map Revision 3)
Extensions
.map, usually as .js.map, .mjs.map or .css.map next to the file it describes
MIME type
application/json; the standard doesn't define its own type
Kind
Plain text (JSON)
Standard
ECMA-426, Source map format specification, 1st edition December 2024, Ecma International
Origins
Created for Google's Closure Inspector debugger; version 3 is the one every tool uses
Made by
TypeScript, esbuild, Vite, webpack, terser, Babel, Sass and most other build tools
Read by
Browser DevTools, Node.js (--enable-source-maps), error-tracking services
Linked with
A sourceMappingURL comment at the end of the code, or a SourceMap HTTP header
Magic number
None; it's JSON starting with {

The basics

What is a source map file?

The JavaScript and CSS that websites send to browsers is rarely the code developers wrote. It has been compiled from TypeScript or JSX, merged from dozens of files into one bundle, and minified, with names shortened and all spacing removed. That's good for speed and bad for debugging: an error at line 1, column 2,817 of app.min.js tells you nothing. A source map records where every piece of the output came from, so browser developer tools can show the original files, with their names, comments and line numbers, while the optimised code runs.

Source maps are generated by build tools, never written by hand. They're named after the file they describe plus .map (app.min.js gets app.min.js.map, styles.css gets styles.css.map), and nothing loads them in normal use: browsers only fetch them when developer tools are open.

Other .map files

The .map extension is also used by unrelated formats, such as the linker map files C and C++ toolchains write, and level files for some game editors. If a .map file doesn't start with {, it isn't a source map.

Anatomy

What's inside a source map

A source map is one JSON object. This is the complete map from our sample-greet.min.js.map sample (formatted for reading), made by terser when it minified an 8-line file, greet.js, into one line: function greet(e){const o="Hello, "+e+"!";return console.log(o),o}greet("Ada");

sample-greet.min.js.map (formatted)
{
  "version": 3,
  "file": "sample-greet.min.js",
  "names": ["greet", "name", "message", "console", "log"],
  "sources": ["greet.js"],
  "mappings": "AAEA,SAASA,MAAMC,GACb,MAAMC,EAAU,UAAYD,EAAO,IAEnC,OADAE,QAAQC,IAAIF,GACLA,CACT,CACAF,MAAM",
  "ignoreList": []
}
  1. 1"version": 3

    The version

    Always the number 3. Versions 1 and 2 were early formats that nothing uses any more.

  2. 2"file": "sample-greet.min.js"

    The generated file

    Optional: the name of the file this map describes. Tools don't rely on it; the link from the code to the map matters more.

  3. 3"names": [ … ]

    Original names

    Identifiers from the original code. The minifier renamed name to e and message to o; mappings point into this list so DevTools can show the real names.

  4. 4"sources": ["greet.js"]

    The original files

    Required. Paths or URLs of the original files, relative to the map. A bundle's map lists every file that went into it.

  5. 5"mappings": "…"

    The mappings

    Required. The position data: for each piece of the generated code, which file, line and column it came from. It's encoded compactly, as explained below.

  6. 6AAEA

    A segment

    One mapping, four numbers in Base64 VLQ: generated column 0, source 0 (greet.js), line 2, column 0. Lines and columns count from 0, so that's line 3 in an editor: function greet(name) {.

  7. 7SAASA

    A segment with a name

    Five numbers: the fifth points into names. This one maps greet in the minified code to greet in the original.

  8. 8, (commas) and ; (semicolons)

    Separators

    Commas separate segments on the same generated line; a semicolon starts the next generated line. The minified code is a single line, so this map has no semicolons.

  9. 9"ignoreList": []

    Code to skip

    Indexes into sources for third-party code, such as libraries, that debuggers should hide or step over. Empty here.

  10. 10(no sourcesContent)

    Original code not included

    This map has no sourcesContent, so a debugger has to fetch greet.js from the server. Maps that include it work on their own, but publish your source code.

Linking

How a browser finds the source map

The generated file points to its map in one of two ways. A comment on its last line is the usual one; an HTTP header does the same without touching the file, and wins if both are present:

Linking a source map
// last line of a JavaScript file
//# sourceMappingURL=sample-app.min.js.map

/* last line of a CSS file */
/*# sourceMappingURL=sample-styles.min.css.map */

# or an HTTP response header, which takes precedence
SourceMap: /js/sample-app.min.js.map
  • The URL is relative to the generated file, not to the page. sample-app.min.js.map means "next to sample-app.min.js".
  • It can be a data: URL. The whole map, base64-encoded, then sits inside the comment. Our sample-inline.js was made this way by tsc --inlineSourceMap --inlineSources: one file, nothing else to fetch, but much bigger.
  • Older syntax: //@ sourceMappingURL and the X-SourceMap header are deprecated. Tools should write //# and SourceMap, though browsers still accept the old forms.
  • No link at all is also an option. A "hidden" source map is generated but not referenced, and is uploaded to an error-tracking service or loaded by hand in DevTools instead.

The format

The fields of a source map

FieldRequiredWhat it holds
versionYesThe number 3
fileNoThe name of the generated file
sourceRootNoA prefix added to every entry in sources, for moving the originals to another folder or server
sourcesYesThe original files, as relative paths or URLs; an entry can be null
sourcesContentNoThe full text of each original file, in the same order as sources
namesNoOriginal identifiers that mappings refer to
mappingsYesThe encoded positions
ignoreListNoWhich sources are third-party code to hide when debugging. Some browsers also read the older x_google_ignoreList
sectionsIndex maps onlyA list of maps with offsets, used instead of sources and mappings

Tools must ignore fields they don't recognise, which lets vendors add their own, usually with an x_ prefix. Additions are being worked on in TC39, the committee behind JavaScript: scopes (for showing original variable names and scopes while debugging), debug IDs (to match a map to its file without relying on URLs) and range mappings.

Under the hood

How the mappings string is encoded

mappings packs thousands of positions into a short string. It's built in three layers:

  1. 1Lines and segments. Each ; starts the next line of the generated file. Within a line, , separates segments, one per mapped piece of code.
  2. 2Fields. A segment has 1, 4 or 5 numbers: the generated column; then the index into sources, the original line and the original column (all counted from 0); then, optionally, an index into names.
  3. 3Relative values. Each number is stored as the difference from the same field in the previous segment, which keeps them small. Only the generated column resets at each new line.
  4. 4Base64 VLQ. Each number is written as Base64 characters carrying 6 bits each (A=0 … Z=25, a=26 … z=51, 0=52 … 9=61, +=62, /=63). Of those 6 bits, the top one (32) means "more characters follow" and the other 5 carry data, lowest bits first. In the finished number, the lowest bit is the sign: odd means negative.

Here are segments from the greet.js map above, decoded. Line and column are shown counted from 1, as an editor shows them:

SegmentDecodedMinified columnOriginal positionPoints at
AAEA0, 0, +2, 01greet.js, line 3, column 1function
SAASA+9, 0, 0, +9, name 010line 3, column 10greet (name: greet)
MAAMC+6, 0, 0, +6, name +116line 3, column 16e, originally name
GACb+3, 0, +1, −1319line 4, column 3const
IAEnC+4, 0, +2, −3543line 6, column 3return: the minifier merged lines 5 and 6 into one statement
OADAE+7, 0, −1, 0, name +250line 5, column 3console
CACAF+1, 0, +1, 0, name −267line 8, column 1greet("Ada")

Working through two characters: S is 18, binary 010010. The continuation bit (32) is off, so the number is complete; its lowest bit is 0, so it's positive; shifting off the sign bit leaves 9. In IAEnC, the fourth number is nC: n is 39, which has the continuation bit set, leaving 7; C is 2, worth 2 × 32 = 64 in the second position; 7 + 64 = 71, odd so negative, and 71 shifted right is 35: −35.

greet.js (the original)
// greet.js: original source for sample-greet.min.js.map
// Free sample from 99helpers.com/file-types/map
function greet(name) {
  const message = "Hello, " + name + "!";
  console.log(message);
  return message;
}
greet("Ada");
sample-greet.min.js (the generated file)
function greet(e){const o="Hello, "+e+"!";return console.log(o),o}greet("Ada");
//# sourceMappingURL=sample-greet.min.js.map

Variants

Index maps: one map made of several

When files are simply joined together, re-encoding every mapping is wasteful. An index map instead lists the existing maps as sections, each with an offset: the line and column in the combined file where that part starts. Sections must be in order and must not overlap.

sample-index.map (shortened)
{
  "version": 3,
  "file": "sample-bundle.js",
  "sections": [
    { "offset": { "line": 0, "column": 0 },
      "map": { "version": 3, "sources": ["greet.js"], "mappings": "AAEA,…", … } },
    { "offset": { "line": 1, "column": 0 },
      "map": { "version": 3, "sources": ["clock.js"], "mappings": "AAEA,…", … } }
  ]
}

Index maps are part of the standard, but fewer tools write them than read them. Our sample-index.map combines the maps of two minified files and is a quick way to test whether a consumer supports sections.

How to

How to generate a source map

ToolSettingVariants
TypeScript (tsc)"sourceMap": trueinlineSourceMap, and inlineSources to embed the originals
esbuild--sourcemap=inline, =external (no comment), =linked
Vitebuild.sourcemap: true'inline', 'hidden'
webpackdevtool: "source-map"hidden-source-map and many faster, less exact options
terser--source-map "url=out.js.map"content= to chain an earlier map

When code passes through several tools, such as TypeScript then a bundler then a minifier, each step has to read the previous map and produce a combined one, or the final map points at an intermediate file. Most bundlers handle this for you. CSS tools, from Sass to PostCSS and esbuild, write .css.map files the same way; our sample-styles.min.css.map comes from esbuild minifying a stylesheet.

Debugging

How DevTools and Node.js use source maps

  • Browser DevTools load the map when they open, then show the original files in the Sources (or Debugger) panel. Breakpoints, stepping and variable names work in the original code, and console messages link to original lines. In Chrome, the Developer resources panel shows whether each map loaded, and you can attach one by hand: right-click the file in Sources and choose "Add source map".
  • Node.js maps stack traces back to the original files when started with --enable-source-maps. Our samples show it: with the flag, an error thrown in minified code is reported at sample-app.ts line 23 instead of .min.js line 1.
  • Error-tracking services receive minified stack traces from users' browsers and use uploaded source maps to turn them into readable ones, which is why hidden maps exist.
  • ignoreList lets DevTools hide library code from stack traces and skip it while stepping, so you only see your own files.

Security

The privacy risk of publishing source maps

A source map published next to your code can be downloaded by anyone, and it can reveal more than the minified code does:

  • sourcesContent is your source code, comments included: TODO notes, internal explanations, commented-out code, and occasionally keys or internal URLs that should never have been in front-end code at all.
  • sources shows your project's layout: folder names, file names and sometimes absolute paths from the build machine, such as a username.
  • names restores the identifiers that minification removed.

Minified code isn't secret either, so a source map rarely creates a new hole, but it makes reading your application much easier. Options, from most to least open:

  • Publish maps with sourcesContent (convenient; fine for open-source code).
  • Publish maps without sourcesContent, so the original files have to be fetched separately and can be kept private.
  • Generate hidden maps, upload them to your error tracker, and don't deploy them. Check they really aren't deployed: a map without a comment is still found at the obvious URL, app.min.js.map.
  • Keep maps on an internal server that only your team can reach, and load them in DevTools by hand.

Whatever you choose, never put secrets in front-end code. Anything a browser receives can be read, with or without a source map.

Troubleshooting

Why isn't my source map working?

SymptomUsual causeFix
"DevTools failed to load source map: Could not load content for …"The map wasn't deployed, or the path in sourceMappingURL is wrongDeploy the map, fix the path (it's relative to the JS file), or remove the comment
The map loads but fails to parseThe server answered the .map request with an HTML page, often a single-page app's fallback to index.htmlExclude .map from the fallback; serve it as application/json
Original files listed but emptyNo sourcesContent, and the sources URLs aren't reachableInclude sourcesContent, or serve the originals where sources points
Breakpoints land a few lines offThe code was changed after the map was made, or one step in the build didn't pass its map onRebuild, and make sure every tool in the chain reads the previous map
Paths like webpack:// or ../../src/ in the file treeNot a problem: tools use their own prefixes or sourceRoot to group filesNothing to fix

Free downloads

Sample source map files to download

Free sample source maps for testing DevTools, error trackers, source map libraries and servers. Each was generated by a real tool from small original files, and decoded with the source-map library to check that a minified position maps back to the right original line and column.

sample-app.min.js.map · 2.1 KBDownloadOpen
Loading…

What's inside sample-app.min.js.map

esbuild made this map when it bundled and minified two TypeScript files, sample-app.ts and format.ts, into sample-app.min.js (also below). Download both to the same folder and open the .js file through a page with DevTools open to see the originals.

  1. version and sources

    Version 3, and two original files, given relative to the map: ../src/format.ts comes first because the bundler placed its code first.

  2. sourcesContent

    Both original files in full, including their comments: the numbered comments 1 to 3 in sample-app.ts explain what to look for, and its /*! comment survives into the minified file.

  3. mappings

    434 characters with no ;, because the minified code is a single line. Decoding it maps the throw new Error in that line back to line 23 of sample-app.ts.

  4. names

    The original identifiers (formatPrice, basket, total, items, checkout…) that esbuild shortened to single letters.

  5. What's missing

    esbuild doesn't write a file field, and there's no sourceRoot or ignoreList: all optional. The link is the //# sourceMappingURL=sample-app.min.js.map comment at the end of sample-app.min.js.

All sample Source map files

  • Bundled TypeScript (esbuild)

    sample-app.min.js.map · 2.1 KB (2,177 bytes)

    The map of two TypeScript files bundled and minified by esbuild, with sourcesContent and names. The original source carries numbered comments explaining what to look for.

    • Testing DevTools and source map libraries on a typical bundle
    • Seeing what `sourcesContent` exposes
  • The minified file it describes

    sample-app.min.js · 483 bytes

    The one-line output that sample-app.min.js.map describes, ending with its sourceMappingURL comment. Runs with node and prints Total: €12.25.

    • Pairing with the map to test loading in DevTools
    • Checking a server serves the `.map` next to the `.js`
  • Minimal map without sourcesContent (terser)

    sample-greet.min.js.map · 235 bytes

    The 235-byte map decoded segment by segment on this page, made by terser. It has file, names and an empty ignoreList, but no sourcesContent.

    • Learning and testing VLQ decoding by hand
    • Testing consumers when originals must be fetched
  • JavaScript with an inline source map (tsc)

    sample-inline.js · 1.7 KB (1,720 bytes)

    Compiled by tsc --inlineSourceMap --inlineSources: the map, with the original TypeScript inside it, is a base64 data: URL in the last line. Runs with node.

    • Testing `data:` URL source maps
    • Showing how much an inline map adds to a file
  • Index map with two sections

    sample-index.map · 1.1 KB (1,141 bytes)

    Combines the maps of two minified files, at lines 1 and 2 of a joined bundle, using sections and offset. Decoded correctly by the source-map library.

    • Checking a consumer supports index maps
    • Testing offset handling
  • CSS source map (esbuild)

    sample-styles.min.css.map · 598 bytes

    The map of a small stylesheet minified by esbuild, with sourcesContent. The .badge:hover rule in the one-line minified CSS maps back to line 15 of the original.

    • Testing CSS source maps in DevTools
    • Comparing JS and CSS maps

Ways to test with them

  • DevTools: put sample-app.min.js and sample-app.min.js.map online together, load the script from a page, open DevTools, and look for sample-app.ts in the Sources panel.
  • Decoders: use sample-greet.min.js.map and the decoded table on this page as expected values for your own VLQ parser.
  • Index maps: feed sample-index.map to your tool. If it complains about a missing mappings field, it doesn't support sections.
  • Servers: request a .map file from your site and check it comes back as JSON (application/json), not as an HTML fallback page.
  • Privacy checks: search your production build for .map files and sourcesContent, and compare with what sample-app.min.js.map reveals.

Free to use for testing, teaching and demos, commercially or not, with no attribution needed. A link back to this page is always appreciated.

Put it online

Have a source map? Give it a link.

Drop a .map file on 99helpers and it gets its own address in seconds. Opening the link shows the JSON as plain text in the browser, and DevTools can load it from there with "Add source map".

Questions

Source map files, frequently asked

What is a .map file?

Usually a source map: a JSON file that links minified or compiled JavaScript or CSS to the original source, so developer tools can show the original. Other programs use .map for unrelated things, such as linker output and game levels.

What is a .js.map file?

The source map for the JavaScript file with the same name minus .map. Browsers only download it when developer tools are open.

Should I deploy source maps to production?

It depends on how much you mind people reading your code. Maps with sourcesContent publish your original source and comments. Many teams generate hidden maps and upload them only to their error tracker.

Do source maps slow down my website?

No. Normal visitors never download them; browsers only fetch them when developer tools are open. Inline maps are the exception: they make the JavaScript file itself much larger.

How do I open a source map?

It's JSON, so any text editor or browser shows it. To use it, open the code it belongs to with browser DevTools, or decode it with a library such as source-map.

What is sourceMappingURL?

A comment at the end of a JavaScript or CSS file, such as //# sourceMappingURL=app.min.js.map, that tells developer tools where the map is. The URL is relative to the file.

What do the letters in mappings mean?

They're numbers in Base64 VLQ: each character carries 5 bits of data and a continuation bit. Groups of 1, 4 or 5 numbers give a generated column, a source file, an original line and column, and optionally a name.

Is the source map format standardised?

Yes. Version 3, long a de facto standard, was published by Ecma International as ECMA-426 in December 2024.

How do I fix "DevTools failed to load source map"?

The file names a map that isn't there. Deploy the .map file at the path the comment gives, relative to the JavaScript file, or remove the comment. It only affects people with DevTools open.

Related formats

Other file types explained

Keep going

Related

Sources

Last reviewed 27 October 2026.