How do I disable source maps in a Vite production build?
By StackSiren · Published
Set build.sourcemap to false in vite.config (or 'hidden' if you upload maps to an error tracker and delete them before deploy), then rebuild and redeploy. Vite's default is already false, so a public .map on your site usually means someone turned maps on.
Bolt, Lovable and many Cursor-exported apps ship Vite + React. Public maps don't invent new secrets on their own — any key already in the minified bundle is still there — but they make original file names, comments and business logic easy to read. The full background is in the exposed source maps guide.
What production source maps reveal
A source map is a .map file that links minified JavaScript back to the code you wrote. Most production maps include the full original sources, so anyone who downloads one can open your src/ tree as if they had the repo.
That typically means:
- File and folder names, component structure and route names
- Comments, TODOs and feature-flag labels left in source
- Internal API paths and configuration that minification had shortened
- Secrets that were already in client code, now easy to search
If a secret is in client code because of a VITE_ prefix or a hard-coded key, turn maps off and rotate that secret. See are VITE_ variables secret? and I leaked my OpenAI API key. Our exposed API key checker searches the live bundle on sites you own.
Step 1: Check your own live site
Only check domains you own.
- Open the site → DevTools → Sources (or Debugger). If you can browse a readable
src/tree, maps are public. - Or open a production JS file and look at the last line. If it ends with
//# sourceMappingURL=..., open that URL. A JSON body with amappingsfield means the map is public.
From a terminal:
SITE=https://yourapp.com
# Find JS assets the homepage loads
curl -s "$SITE/" | grep -oE '/assets/[^"]+\.js' | sort -u | head
# For one asset, look for the sourceMappingURL comment
JS=/assets/index-abc123.js # replace with a real path from above
curl -s "$SITE$JS" | tail -c 200
echo
# If you see sourceMappingURL=index-abc123.js.map, request it
curl -sI "$SITE$JS.map" | head -5
curl -s "$SITE$JS.map" | head -c 200
A 404 / 403 is fine. A 200 with JSON that includes "mappings" is a public map. Some SPA hosts return index.html with status 200 for unknown paths — check the body starts with {, not <!DOCTYPE.
Step 2: Turn maps off in Vite
Vite documents build.sourcemap as boolean | 'inline' | 'hidden', default false.
Open vite.config.ts (or .js) and set:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
build: {
sourcemap: false, // do not emit .map files in production
},
});
Notes from Vite's docs:
| Value | What it does |
|---|---|
false (default) |
No production maps |
true |
Separate .map files + a sourceMappingURL comment in the JS |
'inline' |
Map embedded in the JS as a data URI — usually worse for size and leakage |
'hidden' |
Separate .map files, no sourceMappingURL comment |
Remove any sourcemap: true or sourcemap: 'inline' someone (or an AI builder) added for debugging. Rebuild (npm run build / pnpm build) and confirm dist/assets/ has no .map files before you redeploy.
Bolt and Lovable
These are standard Vite projects under the hood. Ask the builder to set build.sourcemap to false in the Vite config and redeploy. If you export to Netlify, Vercel or another static host, the same config applies — don't generate maps you don't need.
Next.js side note
If a project uses Next.js instead of Vite, production browser maps are off unless productionBrowserSourceMaps is true in next.config. Remove it or set it to false.
Step 3: Keep readable stack traces with hidden maps (Sentry)
Error trackers need maps; visitors don't. Sentry's Vite upload guide shows the safe pattern:
- Set
build.sourcemap: 'hidden'so maps are generated without a browser-facing comment. - Use
@sentry/vite-pluginto upload them during the production build. - Set
sourcemaps.filesToDeleteAfterUploadso.mapfiles are removed before deploy.
Sketch (replace org/project; store the auth token in CI, not in the repo):
import { defineConfig } from "vite";
import { sentryVitePlugin } from "@sentry/vite-plugin";
export default defineConfig({
build: {
sourcemap: "hidden",
},
plugins: [
// other plugins first…
sentryVitePlugin({
org: "your-org",
project: "your-project",
authToken: process.env.SENTRY_AUTH_TOKEN,
sourcemaps: {
filesToDeleteAfterUpload: ["./dist/**/*.map"],
},
}),
],
});
'hidden' alone is not enough: the .map files still exist on disk, and anyone who guesses the URL can download them if you deploy the folder. Always delete after upload, or configure the host to refuse *.map.
Vercel has a Protected Source Maps option under Deployment Protection that returns 404 to the public for .map files. That helps for maps served from the deployment, but it does not cover maps inlined into JavaScript. Prefer not generating public maps at all.
Step 4: Redeploy and re-check
- Rebuild with the new config.
- Confirm the build output has no
.mapfiles (or that your upload plugin deleted them). - Deploy.
- Re-run the curl checks from Step 1 against production.
If DevTools still shows original sources, hard-refresh or try a private window — CDNs and service workers can cache old assets.
Common ways maps end up public
- Someone set
sourcemap: truefor debugging and left it on for production. Vite's default isfalse; an explicittrueis almost always accidental for a public deploy. - An AI builder or template copied a config that enables maps so stack traces look nice in the browser. Prefer hidden maps + an error tracker instead.
'hidden'without cleanup. Maps are generated and copied intodist, then the whole folder is deployed. Guesses like/assets/index-….js.mapstill work.- A second build tool (a framework plugin, Rolldown/Rollup override, or a CI step) emits maps even when Vite's top-level option looks off. Always inspect the build output folder before you ship.
If you find maps and also find a secret in the same bundle, treat the secret as leaked: rotate it, then fix how it got into client code. The exposed API keys guide covers that path end to end.
Related reading
- Exposed source maps guide
- Are VITE_ environment variables secret?
- I leaked my OpenAI API key. What should I do now?
FAQ
Is Vite's default already safe?
Yes for maps: build.sourcemap defaults to false. Public maps mean the option was turned on, or another tool emitted them.
Does turning maps off hide API keys? No. Keys in client bundles stay readable in the minified JS. Move secrets server-side and rotate them; maps only make discovery easier.
Is sourcemap: 'inline' OK?
Almost never for production. It embeds the map in every JS file, so you ship more bytes and the original source travels with the bundle.
What about 'hidden' without deleting files?
Browsers won't auto-load the map, but the files can still be downloaded if deployed. Pair 'hidden' with upload-then-delete (or block *.map on the host).
How do I check this without guessing paths?
StackSiren's free scan looks for sourceMappingURL comments on same-origin scripts for sites you own and requests a sample of those map URLs. It won't catch inlined data-URI maps or orphan .map files with no comment.
Bolt / Lovable won't show me vite.config — what then?
Ask the builder in chat to set build.sourcemap to false and redeploy. After export to your own repo, edit the config yourself and verify dist before the next deploy.
Fix guides for this topic
Platform checklists: Bolt · Lovable