Debug Minified JavaScript: Source Maps and DevTools

Debug Minified JavaScript: Source Maps and DevTools

Debug minified JavaScript without guessing: Chrome pretty-print, source maps in production, and a local unminify step when maps are missing.

22.12.2025
7 min read
Share this article:
JavaScript
Unminify
Debugging
Development
Code
Tools
Tutorial

The problem with minified code in production

A production TypeError on `main.js:1:245` is not the same job as “paste this into an online unminifier.” Minification strips whitespace and comments; mangling renames functions to `a`, `b`, `c`. Pretty-print restores shape. Only a source map restores original names. If maps are missing and you need a local copy, then use the JavaScript unminifier — knowing identifiers stay mangled.

Use source maps when they exist — original names and real stack traces
Pretty-print in Chrome DevTools (or VS Code) without leaving the session
Know what unminify cannot do: mangled names do not come back
Reach for a local formatted copy only when maps are missing
Debug third-party minified libraries with string literals as landmarks

When production JavaScript is unreadable

Debug situations you will actually hit

These are debugging problems. Unminify is one tactic — not the default.

Developer analyzing minified JavaScript code on screen
Production stack trace points at column 12 000 on a single line
A vendor bundle has no source map and you need to see control flow
A performance issue only reproduces in the minified build
You are reviewing a third-party script you are allowed to inspect
You saved a `.min.js` file and need to read it in an editor
What unminify cannot restore

Formatting is not decompilation. Treat these limits as hard:

Developer workspace with Chrome DevTools showing debugging techniques for JavaScript

Limitations:

Mangled identifiers stay mangled: `a`, `b`, `c` will not become `getUserProfile`
Deleted comments are gone
Dead code removed by the minifier cannot be recovered
Indentation and line breaks come back; original names do not
Aggressive transforms (inlining, folding) can stay hard to follow even after pretty-print

What works:

Restore indentation and wrapping
Spaces around operators and keywords
One statement per line so breakpoints land on readable lines
Easier scanning of `if` / `for` / `return` structure
Pretty-print in DevTools on the live file, without copying it out

When to unminify vs pretty-print

Maps first, then pretty-print, then a local copy

Do not start by pasting into a tool. Walk this order — the unminify JavaScript page is step 3, when maps are missing.

JavaScript unminification tool interface showing minified and beautified code

1
Look for a source map

In DevTools → Sources, check for original files next to the bundle, a `.map` sibling, or a `//# sourceMappingURL=` comment. If a map loads, debug there and stop.

2
Pretty-print in the browser or editor

Chrome Sources: the `{}` Pretty Print control formats the file in place. VS Code: Format Document (built-in JS formatter or Prettier) on a saved `.min.js`. Same limit: names stay mangled.

3
Unminify locally only if you need a file copy

No map, and you want indented source on disk or in another tool: paste into unminify JavaScript. Processing stays in the browser. Indent size and character are the format knobs — not a deobfuscator.

4
Navigate with literals, not names

Search for unique strings, URLs, and error messages. Follow `if` / `return` / `.then(` patterns. Do not wait for `a` to become a real identifier.

Example:

Before (minified):

function a(b,c){return b+c}const d=a(5,3);console.log(d);

After (unminified):

function a(b, c) { return b + c } const d = a(5, 3); console.log(d);
A production TypeError, without guessing

Pretty-print (or a source map) should come before copying a megabyte of bundle into an editor.

Visualization of debugging minified JavaScript code with magnifying glass revealing errors

Minified code:

!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return ...

Unminified code (preview):

!function(e, t) { "object" == typeof module && "object" == typeof module.exports ? module.exports = e.document ? t(e, !0) : function(e) { if (!e.document) throw new Error("jQuery requires a window with a document"); return t(e) } : t(e) }("undefined" != typeof window ? window : this, function(e, t) { var n = [], r = e.document, i = n.slice, o = n.concat, s = n.push, a = n.indexOf, u = {}, c = u.toString, l = u.hasOwnProperty, f = {}, p = "2.3.1", d = function(e, t) { return new d.fn.init(e, t) }, h = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; // ... rest of formatted code });

Source maps: the best production debug path

What a source map actually does

A `.map` file records how minified positions map back to original sources. DevTools can then show real file names, original identifiers, and breakpoints in the code you wrote — which no unminifier can reconstruct.

Workflow diagram showing how JavaScript Source Maps connect minified code to original source
Original variable and function names
Breakpoints in your source files, not in one 400 KB line
Stack traces that name the functions you recognize
Debugging production without shipping an unminified bundle to users
How to emit maps in the build

Webpack 5: set `devtool` (do not pass a removed `sourceMap: true` flag to TerserPlugin). Vite: `build.sourcemap: true` or `'hidden'`. Standalone Terser can still attach a map object as below.

Terser

const terser = require('terser'); const result = await terser.minify(code, { sourceMap: { filename: 'app.min.js', url: 'app.min.js.map' } });

Webpack

module.exports = { mode: 'production', devtool: 'hidden-source-map', };

Debugging with browser DevTools

Pretty Print in Chrome DevTools

Chrome (and other Chromium DevTools) can format the file you are already inspecting. That is faster than exporting the bundle when you only need to read the crashing line. VS Code’s Format Document on a saved `.min.js` is the editor equivalent — still not a source map.

Chrome DevTools Sources panel with Pretty Print button highlighted
1
Open DevTools (F12 or Cmd+Option+I)
2
Open the Sources panel and select the minified file
3
Click the `{}` Pretty Print control (status bar of the editor)
4
Jump to the column from the stack trace on the formatted view
5
If a source map is present, switch to the original file instead
Breakpoints after the code is readable

Once DevTools (or an editor) has formatted the file, line numbers refer to the pretty-printed view unless a map is active:

Tips:

Set breakpoints on formatted lines, then reload to catch the next hit
Inspect values even when the binding is named `a` — the runtime value is still real
Use the console on the paused call stack to evaluate expressions
Step line by line; pretty-print makes step-over usable
Read the stack: frames still map to the minified file if no map loaded

When you still need a local formatted copy

Formatters vs the dedicated unminify URL

These options re-indent JavaScript. None of them restore mangled names. The expand-minified-JS job lives on unminify JavaScript. The sibling beautify JavaScript page is the formatter URL; minify JavaScript is the inverse.

FastMinify — Unminify JS

Browser-local unminifier: paste a minified snippet, get indented output. Indent size and spaces vs tabs only. Nothing is uploaded.

Pros:
Runs in the browser
No install
Dedicated unminify URL
Indent controls
Cons:
Formatting only — not a decompiler

VS Code + Prettier

Save the file and run Format Document. This is the usual “unminify in VS Code” path: same readability gain as pretty-print, still no original identifiers.

Pros:
Stays in the editor
Prettier is a common team default
Works offline
Cons:
You need the file on disk
No name recovery

JS Beautifier

Open-source formatter (js-beautify) available as a library, CLI, and various web UIs. Same class of tool: whitespace and structure, not original symbols.

Pros:
Open-source
CLI for scripts
Configurable wrap rules
Cons:
Still not a source map

What to do next

Debug minified JavaScript in this order: source maps if they exist, pretty-print in DevTools or VS Code if you only need to read the crashing line, and a local unminifier only when you need a formatted copy and maps are missing. The tool does not undo mangling. Fix the build so the next incident has maps.

Maps missing and you need indented source locally? Use the browser unminifier — then go back to DevTools.

Emit source maps in production (`hidden-source-map` / Vite `'hidden'` unless you intentionally expose sources)
Pretty-print in DevTools before copying a bundle out of the browser
Use unminify for a local readable copy, not as the first debug click
Treat mangled names as lost without maps
Keep an unminified development build for everyday debugging
Share this article
Share this article: