Guides

Exposed JavaScript source maps: how to check and fix

A source map is a file that turns your minified JavaScript back into the original code. If your production site serves it publicly, anyone can read your source files, comments and file structure. To check, look at the end of your main JavaScript file for a sourceMappingURL line, then open that address or add .map to the file name. To fix it, stop generating maps for production, or do not upload them.

What a source map is

When you build a site, tools such as Vite, webpack and Next.js combine and minify your code into a few hard-to-read JavaScript files. A source map is a separate file, usually ending in .js.map, that records how to turn that output back into your original files. Browser developer tools use it so you can debug the code you wrote instead of the minified version.

Most source maps are JSON with fields such as version, sources, sourcesContent and mappings. The sourcesContent field often holds the full text of every original source file.

A JavaScript file points to its map with a comment on its last line, for example //# sourceMappingURL=index-4f2a9c.js.map, or with a SourceMap HTTP header.

How to check your own site

  1. Open your live site in Chrome or Firefox and open developer tools (F12, or right-click and Inspect).
  2. Go to the Network tab, reload the page, and click your main .js file (often in /assets/ or /_next/static/).
  3. Open the Response and scroll to the very end. Look for a line starting //# sourceMappingURL=. If it is there, copy the file name.
  4. Open that address in a new tab, for example https://your-site.com/assets/index-4f2a9c.js.map. If there is no comment, try the script address with .map added at the end.
  5. If you see a large block of JSON starting with {"version":3, your map is public.

A terminal check does the same thing:

curl -s https://your-site.com/assets/index-4f2a9c.js.map | head -c 200

Be careful with one trap. Many single-page apps answer every unknown address with the home page and a 200 status. A 200 is not proof. The response must be the JSON map, not your HTML.

You can also open the Sources tab in developer tools. If you see your original folders and files (such as src/App.tsx) and not just minified bundles, a map was loaded. Check each of the main JavaScript files, not only one.

Why a public source map matters

Your JavaScript is already public, so a map does not reveal something that was fully hidden. What it changes is how easy your code is to read and search:

  • It exposes original file names, folder structure, variable names and comments.
  • It exposes internal API routes, admin pages, feature flags and business logic that are hard to find in minified code.
  • It can include things developers leave in source: commented-out keys, test credentials, internal URLs and TODO notes.
  • It makes it quicker for someone to look for weaknesses in your code.

Keys are the part to be careful with. A secret that your code uses in the browser is already in the bundle, and the map is not the only way it leaks. But a map can contain hard-coded values and comments that never reached the bundle. If you find a secret in a map, rotate it. See Leaked API keys in your frontend.

How to fix it

The aim is simple: do not publish .map files for production. Then redeploy and check again.

Vite (including many Lovable and Bolt projects)

Vite does not generate maps by default, so someone or something turned them on. In vite.config.ts:

export default defineConfig({
  build: { sourcemap: false },
})

The value 'hidden' still creates map files but leaves out the comment in the JavaScript. If the files are in your deploy folder they are still public. Only use 'hidden' if you upload the maps to an error-tracking tool and do not publish them.

Next.js

Maps for browser code are off by default. Look in next.config.js (or .mjs, .ts) and remove this setting if it is there:

module.exports = {
  productionBrowserSourceMaps: false, // or delete the line
}

If you use an error-tracking plugin that uploads maps, check its settings for an option to delete the maps after upload, so they are not left in the build output.

webpack and Create React App

For webpack, set devtool so production builds do not ship maps:

module.exports = {
  mode: "production",
  devtool: false, // or "hidden-source-map" if you upload maps elsewhere
}

For Create React App, turn maps off in the build command:

GENERATE_SOURCEMAP=false npm run build

Any other setup

  • Delete maps from the folder you deploy: find dist -name '*.map' -delete (use your real output folder name).
  • Or have your host or server return 404 for any address ending in .map.

After you change it

  1. Build and redeploy.
  2. Repeat the check above. The .map address should return 404, not JSON.
  3. Purge your CDN cache if you use one, since an old map can stay cached.
  4. If you found anything sensitive in the map, rotate it.

How DeployVet fits

The free check looks at your site's main JavaScript files (up to the first five from your own domain). For each, it looks for the map in the SourceMap or X-SourceMap response header, in the sourceMappingURL comment at the end of the script, and at the script address with .map added, and requests the file. It counts a response only if it is a real source map (a JSON file with version 3 and a list of sources), so a normal web page returned at that address is not mistaken for one. Large maps are read up to about 300 KB. If one is found, it reports "JavaScript source maps are public" as a medium finding. The Free check shows your single most important finding in full and counts the rest, so if source maps are not your biggest issue, the full detail is in the paid Scan.

This check has limits. It looks at only the first five scripts on your own domain, it does not follow maps that are embedded inside the script itself or hosted on another domain, and it does not find map files that nothing links to. A clean result does not prove your maps are private. Use the manual check above as well.

FAQ

Is a public source map a security hole?

It is an exposure, not a break-in. Your minified code is already public, but a map makes it much easier to read and search, and may include comments and files that are not in the bundle. We rate it medium.

Do hidden source maps fix it?

Only if you do not publish the map files. Hidden maps remove the comment from your JavaScript, but a map file in your public folder can still be requested by anyone who guesses the address.

Will turning source maps off break my site?

No. Maps are only used for debugging. Your site runs the same without them.

Can I keep maps for error tracking?

Yes. Upload the maps to your error-tracking tool during the build, and do not publish them with the site.

Does DeployVet check for source maps?

Yes, it checks up to five of your own scripts using the header, the comment and the .map address, as described above. It can still miss maps hosted on another domain or not linked from those scripts, so check yourself too.

Check your site for free

DeployVet checks your live site from the outside, like a stranger would. You get a score out of 100 and the most important finding with a fix.

DeployVet has three plans. The Free check is $0. A one-time Scan is $7. The Fix it pack is $10 once and adds 30 days of "Did I fix it?" re-checks and score history. For paid plans you pay first, then the scan runs.

Run the free check

DeployVet is an outside-in check, not an audit, a penetration test or a certification. It sees only what a stranger can reach from the public internet, and a clean result is not a guarantee. Only check sites you own or have permission to check. See the methodology for what is and is not checked.

More guides

All guides