The short version
- Find them: one search across
src/shows how many you have. - Strip at build time: Next.js has a compiler option; Vite can drop them during the build.
- Keep real errors: drop
console.loganddebugger, keepconsole.error. - Stop new ones: a lint rule catches them before they ship.
1. Why it matters
- Data leaks. Logging a whole user or API response prints emails, IDs and sometimes tokens for anyone with devtools open.
- It looks unfinished. Developers who check out your launch will open the console.
debuggerstatements pause the page for any visitor with devtools open.
2. Find what you have
grep -rnE "console\.log|debugger" src app components --include=*.{js,jsx,ts,tsx} | wc -lRemove anything that logs secrets or whole user objects by hand, since those also show up in server logs. Then let the build strip the rest.
3. Next.js: the removeConsole option
Next.js can remove console calls from your application code during the build. Keep errors and warnings so real problems still surface:
/** @type {import('next').NextConfig} */
const nextConfig = {
compiler: {
removeConsole:
process.env.NODE_ENV === "production"
? { exclude: ["error", "warn"] }
: false,
},
};
module.exports = nextConfig;4. Vite: drop at build time
On Vite versions that use esbuild for transforms, drop console and debugger only for production builds:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig(({ command }) => ({
plugins: [react()],
esbuild:
command === "build"
? { drop: ["debugger"], pure: ["console.log", "console.debug"] }
: {},
}));pure removes only the listed calls, so console.error survives. If your Vite version uses a different transformer, check its build docs for the equivalent drop option; the lint rule below works on every version.
5. Stop new ones with a lint rule
rules: {
"no-console": ["warn", { allow: ["error", "warn"] }],
"no-debugger": "error",
}For logging you actually need in production, use console.error for real failures or an error tracker like Sentry, which captures context without printing it to every visitor.
Before you ship
- No console.log calls print user data, tokens or full API responses.
- The production build strips console.log and debugger.
- console.error still reports real failures.
- A lint rule flags new debug logging.
Check your live site in 60 seconds
ShipReady scans your deployed URL and the JavaScript visitors actually download: leaked keys, Supabase exposure, unprotected API routes, titles and share images. Secret findings unlock only after you verify you own the site.
Free scan, no signup, no code upload.FAQ
Some console messages are still there after the build. Why?
Build options usually only strip your application code, not third-party packages. A few library messages are normal. What matters is that your own debug output is gone.
Is console.log a security vulnerability?
Not by itself. It becomes one when it prints secrets, tokens or other users' data, which AI-generated debug code often does.
Keep reading
Sources: Next.js: compiler options (removeConsole) · ESLint: no-console rule