Silence Console Logs in Next.js 16+ for Production
A Simple Two-step Solution to Manage Console Outputs in Next.js Applications

⚡ Next.js Implementation Guides
In-depth Next.js guides covering App Router, RSC, ISR, and deployment. Get code examples, optimization checklists, and prompts to accelerate development.
I was pushing a Next.js 16+ build toward production when the console turned into a disaster. Every debug console.log we relied on during dev spammed the production logs. I wanted a surgical fix: keep the messages locally, silence them in prod. Here’s the exact two-step patch I dropped into the project.
First, create a tiny side-effect module that overrides console.log whenever NODE_ENV isn’t development. Place it somewhere you can import from the root layout so it executes on the server before anything else runs.
// File: lib/disable-console.ts
const noop = (..._args: unknown[]) => {};
if (process.env.NODE_ENV !== "development") {
console.log = noop;
}
export {};
This swaps console.log for a harmless no-op function outside dev. The export {} keeps TypeScript happy so it treats the file as a module. With this imported from the root layout, server-side code no longer emits logs in production.
Next, wire up a tiny client component that applies the same override in the browser. React’s useEffect is enough. Render this component near the top of the layout so it runs as soon as the app hydrates.
// File: components/system/disable-console-logs.tsx
"use client";
import { useEffect } from "react";
const noop = (..._args: unknown[]) => {};
export function DisableConsoleLogs() {
useEffect(() => {
if (process.env.NODE_ENV !== "development") {
console.log = noop;
}
}, []);
return null;
}
Finally, patch the root layout to import both helpers. That guarantees the override runs for server renders and client hydration.
// File: app/layout.tsx
import "@/lib/disable-console";
import { DisableConsoleLogs } from "@/components/system/disable-console-logs";
// ...rest of the layout imports
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="de">
<body>
<DisableConsoleLogs />
{/* your providers/components */}
</body>
</html>
);
}
And that’s the hack. In development you still get full logging, while production quietly ignores every console.log without touching the rest of your codebase. No third-party logger, no environment gymnastics—just a couple of lines, purposefully placed. Let me know in the comments if you have questions, and subscribe for more practical development guides. Thanks, Matija