Skip to main content
The optimization configuration controls webpack’s built-in optimization features, including code splitting, minification, and module concatenation.

Basic Configuration

webpack.config.js
module.exports = {
  optimization: {
    minimize: true,
    splitChunks: {
      chunks: 'all'
    }
  }
};

Optimization Options

optimization.minimize
boolean
Enable/disable minification.
optimization: {
  minimize: true
}
Default: true in production mode, false otherwise
optimization.minimizer
array
Customized minifier plugins.
const TerserPlugin = require('terser-webpack-plugin');

optimization: {
  minimizer: [
    new TerserPlugin({
      terserOptions: {
        compress: {
          drop_console: true
        }
      }
    })
  ]
}
Use '...' to extend default minimizers:
optimization: {
  minimizer: [
    '...', // extend defaults
    new CssMinimizerPlugin()
  ]
}
optimization.moduleIds
'natural' | 'named' | 'deterministic' | 'size' | false
Algorithm for module IDs.
optimization: {
  moduleIds: 'deterministic'
}
  • 'natural': Numeric IDs in order of usage
  • 'named': Readable IDs for debugging
  • 'deterministic': Short numeric hash IDs for caching
  • 'size': Numeric IDs focused on minimal bundle size
  • false: Custom algorithm via plugin
Default: 'deterministic' in production, 'named' in development
optimization.chunkIds
'natural' | 'named' | 'deterministic' | 'size' | 'total-size' | false
Algorithm for chunk IDs.
optimization: {
  chunkIds: 'deterministic'
}
  • 'deterministic': Short numeric hash IDs (recommended for caching)
  • 'named': Readable IDs for debugging
  • 'size': IDs focused on minimal initial download
  • 'total-size': IDs focused on minimal total download
Default: 'deterministic' in production, 'named' in development

Code Splitting

optimization.splitChunks
object | false
Configure chunk splitting behavior.
optimization: {
  splitChunks: {
    chunks: 'all',
    minSize: 20000,
    maxSize: 244000,
    minChunks: 1,
    maxAsyncRequests: 30,
    maxInitialRequests: 30,
    cacheGroups: {
      defaultVendors: {
        test: /[\\/]node_modules[\\/]/,
        priority: -10,
        reuseExistingChunk: true
      },
      default: {
        minChunks: 2,
        priority: -20,
        reuseExistingChunk: true
      }
    }
  }
}
Set to false to disable splitting.

Split Chunks Options

splitChunks.chunks
'all' | 'async' | 'initial' | function
Which chunks to optimize.
chunks: 'all' // all chunks
chunks: 'async' // only async chunks
chunks: 'initial' // only initial chunks
splitChunks.minSize
number
Minimum size (in bytes) for a chunk to be generated.
minSize: 20000 // 20kb
Default: 20000
splitChunks.maxSize
number
Maximum size hint for chunks.
maxSize: 244000 // 244kb
splitChunks.minChunks
number
Minimum times a module must be shared before splitting.
minChunks: 2
Default: 1
splitChunks.maxAsyncRequests
number
Maximum number of parallel requests for on-demand loading.
maxAsyncRequests: 30
Default: 30
splitChunks.maxInitialRequests
number
Maximum number of parallel requests at entry point.
maxInitialRequests: 30
Default: 30
splitChunks.cacheGroups
object
Define custom chunk groups.
cacheGroups: {
  vendor: {
    test: /[\\/]node_modules[\\/]/,
    name: 'vendors',
    chunks: 'all',
    priority: 10
  },
  common: {
    minChunks: 2,
    priority: 5,
    reuseExistingChunk: true
  },
  styles: {
    test: /\.css$/,
    name: 'styles',
    chunks: 'all',
    enforce: true
  }
}
Cache group properties:
  • test: Condition to match modules
  • name: Name of the split chunk
  • priority: Priority when a module matches multiple groups
  • reuseExistingChunk: Reuse existing chunk if available
  • enforce: Create chunk even if it violates size limits

Runtime Chunk

optimization.runtimeChunk
boolean | 'single' | 'multiple' | object
Extract runtime code into a separate chunk.
// Single runtime chunk for all entry points
runtimeChunk: 'single'

// Separate runtime chunk for each entry
runtimeChunk: 'multiple'

// Custom name
runtimeChunk: {
  name: (entrypoint) => `runtime-${entrypoint.name}`
}
Default: false

Tree Shaking

optimization.usedExports
boolean | 'global'
Detect and mark unused exports.
optimization: {
  usedExports: true // analyze per runtime
  // or
  usedExports: 'global' // analyze globally
}
Default: true in production
optimization.providedExports
boolean
Determine exports for each module.
optimization: {
  providedExports: true
}
Default: true
optimization.sideEffects
boolean | 'flag'
Skip modules without side effects.
optimization: {
  sideEffects: true // use + analyze code
  // or
  sideEffects: 'flag' // only use package.json flag
}
Default: true in production

Module Concatenation

optimization.concatenateModules
boolean
Safely concatenate modules into a single module (scope hoisting).
optimization: {
  concatenateModules: true
}
Default: true in production
optimization.innerGraph
boolean
Enable inner module graph analysis for better tree shaking.
optimization: {
  innerGraph: true
}
Default: true in production

Other Optimizations

optimization.mangleExports
boolean | 'deterministic' | 'size'
Rename exports to shorter names.
optimization: {
  mangleExports: 'deterministic' // or 'size' or true
}
Default: 'deterministic' in production
optimization.mangleWasmImports
boolean
Reduce WASM size by renaming imports.
optimization: {
  mangleWasmImports: true
}
Default: false
optimization.removeAvailableModules
boolean
Remove modules already available in parent chunks.
optimization: {
  removeAvailableModules: true
}
Default: true in production
optimization.removeEmptyChunks
boolean
Remove empty chunks.
optimization: {
  removeEmptyChunks: true
}
Default: true
optimization.mergeDuplicateChunks
boolean
Merge chunks with identical modules.
optimization: {
  mergeDuplicateChunks: true
}
Default: true
optimization.flagIncludedChunks
boolean
Flag chunks as loaded when they contain all modules from another chunk.
optimization: {
  flagIncludedChunks: true
}
Default: true in production
optimization.emitOnErrors
boolean
Emit assets even when errors occur.
optimization: {
  emitOnErrors: false
}
Default: false
optimization.realContentHash
boolean
Use real content hash instead of build-time hash.
optimization: {
  realContentHash: true
}
Default: true in production
optimization.nodeEnv
string | false
Set process.env.NODE_ENV to a specific value.
optimization: {
  nodeEnv: 'production'
}
Default: false or value from mode
optimization.portableRecords
boolean
Generate records with relative paths.
optimization: {
  portableRecords: true
}
Default: false

Common Patterns

Production Optimization

webpack.config.js
module.exports = {
  mode: 'production',
  optimization: {
    minimize: true,
    minimizer: ['...'],
    moduleIds: 'deterministic',
    chunkIds: 'deterministic',
    runtimeChunk: 'single',
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          priority: 10
        }
      }
    },
    usedExports: true,
    sideEffects: true,
    concatenateModules: true
  }
};

Vendor Code Splitting

webpack.config.js
module.exports = {
  optimization: {
    splitChunks: {
      cacheGroups: {
        react: {
          test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
          name: 'react',
          chunks: 'all',
          priority: 20
        },
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendor',
          chunks: 'all',
          priority: 10
        },
        common: {
          minChunks: 2,
          priority: 5,
          reuseExistingChunk: true
        }
      }
    }
  }
};

CSS Splitting

webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
  optimization: {
    minimizer: [
      '...',
      new CssMinimizerPlugin()
    ],
    splitChunks: {
      cacheGroups: {
        styles: {
          name: 'styles',
          type: 'css/mini-extract',
          chunks: 'all',
          enforce: true
        }
      }
    }
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css'
    })
  ]
};

Development Optimization

webpack.config.js
module.exports = {
  mode: 'development',
  optimization: {
    minimize: false,
    moduleIds: 'named',
    chunkIds: 'named',
    runtimeChunk: 'single',
    removeAvailableModules: false,
    removeEmptyChunks: false,
    splitChunks: false
  }
};

Size-Optimized Build

webpack.config.js
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true,
            drop_debugger: true,
            pure_funcs: ['console.log']
          },
          mangle: true
        }
      })
    ],
    moduleIds: 'size',
    chunkIds: 'size',
    mangleExports: 'size',
    concatenateModules: true,
    usedExports: true,
    sideEffects: true
  }
};