Skip to main content
The devtool option controls if and how source maps are generated. Source maps provide a way to map minified/compiled code back to the original source code for debugging.

Basic Configuration

webpack.config.js
module.exports = {
  devtool: 'source-map' // production
  // or
  devtool: 'eval-source-map' // development
};

DevTool Option

devtool
string | false
Choose a style of source mapping.
devtool: 'source-map'
Set to false to disable source maps.

Source Map Types

Production

Recommended for production builds:
Like source-map but doesn’t add a reference comment to the bundle.
devtool: 'hidden-source-map'
  • Quality: Original source
  • Build: Slowest
  • Rebuild: Slowest
  • Production: Yes
  • File: Separate .map file (not referenced)
Useful when you want to upload source maps to error reporting tools but not expose them to end users.
Source map without the source content.
devtool: 'nosources-source-map'
  • Quality: Only line numbers
  • Build: Slowest
  • Rebuild: Slowest
  • Production: Yes
  • File: Separate .map file
Shows stack traces without exposing source code. Good for privacy.

Development

Recommended for development builds:
Similar to eval-source-map, each module is executed with eval() but with lower quality.
devtool: 'eval-cheap-source-map'
  • Quality: Transformed code (loader output)
  • Build: Fast
  • Rebuild: Fast
  • Production: No
  • File: Inline
Maps to transformed code (after loaders). Line-only mapping.
Like eval-cheap-source-map but with better quality.
devtool: 'eval-cheap-module-source-map'
  • Quality: Original source (loader input)
  • Build: Medium
  • Rebuild: Fast
  • Production: No
  • File: Inline
Maps to original source (before loaders). Line-only mapping. Good balance for development.
Each module is executed with eval() without source map.
devtool: 'eval'
  • Quality: Generated code
  • Build: Fastest
  • Rebuild: Fastest
  • Production: No
  • File: None
Fastest option but no source mapping. Only shows generated code.

Other Options

Source map as a DataUrl in the bundle.
devtool: 'inline-source-map'
  • Quality: Original source
  • Build: Slowest
  • Rebuild: Slowest
  • Production: No
  • File: Inline DataUrl
Embeds the entire source map as a data URL. Large bundle size.
Source map without column mappings.
devtool: 'cheap-source-map'
  • Quality: Transformed code
  • Build: Fast
  • Rebuild: Medium
  • Production: No
  • File: Separate .map file
Line-only mapping to transformed code.
Source map without column mappings from original source.
devtool: 'cheap-module-source-map'
  • Quality: Original source
  • Build: Medium
  • Rebuild: Medium
  • Production: No
  • File: Separate .map file
Line-only mapping to original source.

Source Map Naming

Source map options follow this naming pattern:
[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
  • inline: Embed source map as DataUrl
  • hidden: Generate source map but don’t reference it
  • eval: Wrap modules in eval() (fast rebuilds)
  • nosources: Exclude source content (only stack traces)
  • cheap: Line-only mapping (no columns)
  • module: Map to original source (before loaders)

Configuration by Environment

Production Configuration

webpack.prod.js
module.exports = {
  mode: 'production',
  devtool: 'source-map',
  output: {
    sourceMapFilename: '[file].map'
  }
};

Development Configuration

webpack.dev.js
module.exports = {
  mode: 'development',
  devtool: 'eval-source-map'
};

Conditional Configuration

webpack.config.js
module.exports = (env, argv) => {
  const isProduction = argv.mode === 'production';
  
  return {
    devtool: isProduction ? 'source-map' : 'eval-source-map'
  };
};

Source Map Output

output.sourceMapFilename
string
Customize source map filename.
output: {
  sourceMapFilename: '[file].map'
  // or
  sourceMapFilename: 'sourcemaps/[file].map[query]'
}
Default: '[file].map[query]'
output.devtoolModuleFilenameTemplate
string | function
Customize module filenames in source maps.
output: {
  devtoolModuleFilenameTemplate: 'webpack://[namespace]/[resource-path]?[loaders]'
  // or function
  devtoolModuleFilenameTemplate: (info) => {
    return `webpack:///${info.resourcePath}`;
  }
}
output.devtoolNamespace
string
Module namespace in source maps.
output: {
  devtoolNamespace: 'my-app'
}

Asset-Specific Source Maps

Webpack 5 allows different devtools per asset type:
webpack.config.js
module.exports = {
  devtool: [
    {
      type: 'javascript',
      use: 'source-map'
    },
    {
      type: 'css',
      use: 'source-map'
    }
  ]
};

Performance Comparison

devtoolbuildrebuildproductionquality
(none)fastestfastestyesbundle
evalfastestfastestnogenerated
eval-cheap-source-mapfastfastnotransformed
eval-cheap-module-source-mapmediumfastnooriginal lines
eval-source-mapslowestfastnooriginal
cheap-source-mapfastmediumnotransformed
cheap-module-source-mapmediummediumnooriginal lines
source-mapslowestslowestyesoriginal
inline-source-mapslowestslowestnooriginal
hidden-source-mapslowestslowestyesoriginal
nosources-source-mapslowestslowestyesno source

Best Practices

// Development
devtool: 'eval-source-map'

// Production
devtool: 'source-map'

// Production (faster builds)
devtool: 'cheap-module-source-map'

// Production (no source code exposure)
devtool: 'hidden-source-map'

// Production (privacy + error tracking)
devtool: 'nosources-source-map'

Error Monitoring Integration

For services like Sentry:
webpack.config.js
const SentryWebpackPlugin = require('@sentry/webpack-plugin');

module.exports = {
  devtool: 'hidden-source-map',
  plugins: [
    new SentryWebpackPlugin({
      include: './dist',
      ignore: ['node_modules', 'webpack.config.js'],
      urlPrefix: '~/static/js'
    })
  ]
};

TypeScript Configuration

For TypeScript projects, also configure tsconfig.json:
tsconfig.json
{
  "compilerOptions": {
    "sourceMap": true
  }
}

CSS Source Maps

Enable source maps in CSS loaders:
webpack.config.js
module.exports = {
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              sourceMap: true
            }
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true
            }
          }
        ]
      }
    ]
  }
};

Disable Source Maps

webpack.config.js
module.exports = {
  devtool: false
  // or omit the option entirely
};

Common Patterns

Multi-Environment Setup

webpack.config.js
module.exports = (env) => {
  const devtoolMap = {
    production: 'source-map',
    development: 'eval-source-map',
    test: 'inline-source-map'
  };
  
  return {
    devtool: devtoolMap[env.NODE_ENV] || 'eval-source-map'
  };
};

Conditional Source Maps

webpack.config.js
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';

module.exports = {
  devtool: shouldUseSourceMap ? 'source-map' : false
};

Docker/Container Builds

webpack.config.js
module.exports = {
  devtool: 'eval-cheap-module-source-map',
  output: {
    devtoolModuleFilenameTemplate: info => 
      path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')
  }
};