Excessive console logging in production can lead to several problems including performance degradation, exposed sensitive information, and cluttered debugging tools. Here’s how to properly handle logging in React applications.
Why Remove Console Logs in Production
- Performance impact: Console operations are synchronous and block the main thread
- Security risk: May accidentally expose sensitive data
- Professionalism: Production apps shouldn’t expose internal logging
- Debugging noise: Makes real issues harder to spot
Solutions for Clean Production Builds
1. Basic Babel Plugin Approach
Install the babel plugin:
npm install babel-plugin-transform-remove-console --save-dev
Add to .babelrc
or babel.config.js
:
{
"plugins": [
["transform-remove-console", { "exclude": ["error", "warn"] }]
]
}
2. Webpack Configuration (for custom setups)
// webpack.config.prod.js
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true, // Remove all console.*
// or selective:
pure_funcs: ['console.log', 'console.debug']
}
}
})
]
}
};
3. Environment-Aware Logging Utility
Create a custom logger (logger.js
):
const logLevels = {
DEBUG: 'debug',
PROD: 'production'
};
const currentLevel = process.env.NODE_ENV === 'production'
? logLevels.PROD
: logLevels.DEBUG;
export const logger = {
log: (...args) => currentLevel === logLevels.DEBUG && console.log(...args),
warn: (...args) => console.warn(...args),
error: (...args) => console.error(...args),
debug: (...args) => currentLevel === logLevels.DEBUG && console.debug(...args)
};
4. TypeScript Advanced Logger (with types)
enum LogLevel {
DEBUG = 0,
PRODUCTION = 1
}
class Logger {
private readonly level: LogLevel;
constructor() {
this.level = process.env.NODE_ENV === 'production'
? LogLevel.PRODUCTION
: LogLevel.DEBUG;
}
public log(...args: any[]): void {
if (this.level === LogLevel.DEBUG) {
console.log('[LOG]', ...args);
}
}
// Add other methods as needed
}
export const logger = new Logger();
Best Practices for Production Logging
- Keep error and warn statements: These are valuable for production debugging
- Use logging levels: Implement debug/info/warn/error severity levels
- Strip in CI pipeline: Remove logs as part of your build process
- User-friendly errors: Log technical details but show clean messages to users
- Performance monitoring: Use proper analytics tools instead of console
Advanced Patterns
1. Conditional Logging with Error Tracking
// Configure early in your app
if (process.env.NODE_ENV === 'production') {
window._trackError = (error) => {
// Send to error tracking service (Sentry, LogRocket, etc.)
errorService.track(error);
console.error('Reported error:', error); // Optional
};
}
// Usage
try {
riskyOperation();
} catch (error) {
if (process.env.NODE_ENV === 'production') {
window._trackError?.(error);
} else {
console.error('Dev error details:', error);
throw error; // Maintain behavior in dev
}
}
2. Production-Only Performance Logging
export const perfLogger = {
start: (label) => {
if (process.env.NODE_ENV === 'production' &&
window.performanceMetricsEnabled) {
console.time(label);
}
},
end: (label) => {
if (process.env.NODE_ENV === 'production' &&
window.performanceMetricsEnabled) {
console.timeEnd(label);
}
}
};
// Usage
perfLogger.start('heavy_operation');
// ... operation code
perfLogger.end('heavy_operation');
Migration Strategy
- Audit existing logs: Search for all
console.*
calls - Categorize logs:
- Remove completely (debug/temporary logs)
- Convert to error/warn (important logs)
- Move to logger utility (conditional logs)
- Educate team: Establish logging guidelines
- Add to code review: Check for proper logging practices
ESLint Rule to Prevent Accidental Logs
Add to your ESLint config:
{
"rules": {
"no-console": [
"error",
{
"allow": ["warn", "error"]
}
]
}
}
For temporary exceptions:
// eslint-disable-next-line no-console
console.log('Temporary debug message');
By implementing these strategies, you’ll maintain valuable debugging capabilities in development while keeping your production builds clean and performant.