Skip to main content
The DllPlugin and DllReferencePlugin work together to split bundles in a way that drastically improves build time performance. The DLL (Dynamic Link Library) concept is used to pre-build vendor libraries that change infrequently.

Overview

DllPlugin creates a manifest file and a DLL bundle. DllReferencePlugin then uses this manifest to reference the pre-built DLL, avoiding the need to rebuild vendor code.

Usage

Step 1: Create DLL Configuration

Create a separate webpack configuration for building the DLL:
// webpack.dll.config.js
const path = require('path');
const webpack = require('webpack');

module.exports = {
  mode: 'development',
  entry: {
    vendor: ['react', 'react-dom', 'lodash']
  },
  output: {
    path: path.resolve(__dirname, 'dll'),
    filename: '[name].dll.js',
    library: '[name]_lib'
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]_lib',
      path: path.resolve(__dirname, 'dll/[name]-manifest.json')
    })
  ]
};

Step 2: Build the DLL

webpack --config webpack.dll.config.js
This creates:
  • dll/vendor.dll.js - The DLL bundle
  • dll/vendor-manifest.json - The manifest

Step 3: Reference DLL in Main Config

// webpack.config.js
const webpack = require('webpack');
const path = require('path');

module.exports = {
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: require('./dll/vendor-manifest.json')
    })
  ]
};

Step 4: Include DLL in HTML

<!DOCTYPE html>
<html>
  <head>
    <title>My App</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- Load DLL first -->
    <script src="dll/vendor.dll.js"></script>
    <!-- Then your app bundle -->
    <script src="dist/app.js"></script>
  </body>
</html>

DllPlugin Configuration

name
string
required
Name of the exposed DLL function. Should match output.library
path
string
required
Absolute path to the manifest JSON file
entryOnly
boolean
default:"true"
If true, only entry modules are exposed
context
string
Context for the manifest file (defaults to webpack context)
format
boolean
If true, manifest is formatted for readability

Examples

Multiple DLL Bundles

// webpack.dll.config.js
module.exports = {
  entry: {
    react: ['react', 'react-dom'],
    vendor: ['lodash', 'axios', 'moment']
  },
  output: {
    path: path.resolve(__dirname, 'dll'),
    filename: '[name].dll.js',
    library: '[name]_lib'
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]_lib',
      path: path.resolve(__dirname, 'dll/[name]-manifest.json')
    })
  ]
};
Reference both:
// webpack.config.js
module.exports = {
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: require('./dll/react-manifest.json')
    }),
    new webpack.DllReferencePlugin({
      manifest: require('./dll/vendor-manifest.json')
    })
  ]
};

Production DLL

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

module.exports = {
  mode: 'production',
  entry: {
    vendor: ['react', 'react-dom', 'lodash']
  },
  output: {
    path: path.resolve(__dirname, 'dll'),
    filename: '[name].[contenthash].dll.js',
    library: '[name]_[contenthash]_lib'
  },
  optimization: {
    minimizer: [new TerserPlugin()]
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]_[contenthash]_lib',
      path: path.resolve(__dirname, 'dll/[name]-manifest.json')
    })
  ]
};

With Add-ons

Combine with HtmlWebpackPlugin:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');

module.exports = {
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: require('./dll/vendor-manifest.json')
    }),
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new AddAssetHtmlPlugin({
      filepath: path.resolve(__dirname, 'dll/vendor.dll.js')
    })
  ]
};

Development vs Production

const isDev = process.env.NODE_ENV === 'development';

module.exports = {
  plugins: [
    isDev && new webpack.DllReferencePlugin({
      manifest: require('./dll/vendor-manifest.json')
    })
  ].filter(Boolean)
};

Complete Example

Directory Structure

project/
├── dll/
│   ├── vendor.dll.js
│   └── vendor-manifest.json
├── src/
│   ├── index.js
│   └── App.js
├── webpack.dll.config.js
└── webpack.config.js

Package.json Scripts

{
  "scripts": {
    "dll": "webpack --config webpack.dll.config.js",
    "build": "npm run dll && webpack --config webpack.config.js",
    "dev": "webpack serve --config webpack.config.js"
  }
}

Full DLL Config

// webpack.dll.config.js
const path = require('path');
const webpack = require('webpack');

module.exports = {
  mode: 'development',
  entry: {
    vendor: [
      'react',
      'react-dom',
      'lodash',
      'axios',
      'moment'
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dll'),
    filename: '[name].dll.js',
    library: '[name]_lib'
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]_lib',
      path: path.resolve(__dirname, 'dll/[name]-manifest.json'),
      context: __dirname
    })
  ]
};

Full Main Config

// webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.js'
  },
  plugins: [
    new webpack.DllReferencePlugin({
      context: __dirname,
      manifest: require('./dll/vendor-manifest.json')
    }),
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ]
};

Performance Benefits

Typical improvements:
  • Initial build: Similar to normal build
  • Rebuild time: 50-90% faster
  • Best for large vendor libraries that rarely change

Example Timings

Without DLL:
- Initial build: 45s
- Rebuild: 8s

With DLL:
- DLL build (once): 15s
- Initial build: 12s
- Rebuild: 2s

When to Use

DllPlugin is beneficial when:
  • You have large, stable vendor libraries
  • Development rebuild time is slow
  • Vendor code changes infrequently
  • Team is doing active development
DllPlugin is mainly for development. For production, modern techniques like SplitChunksPlugin and caching are often better.

Modern Alternatives

Webpack 5 Caching

module.exports = {
  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [__filename]
    }
  }
};

SplitChunksPlugin

optimization: {
  splitChunks: {
    cacheGroups: {
      vendor: {
        test: /[\\/]node_modules[\\/]/,
        name: 'vendors',
        chunks: 'all'
      }
    }
  }
}

Troubleshooting

Manifest Not Found

Ensure DLL is built before main build:
"scripts": {
  "prebuild": "npm run dll",
  "build": "webpack"
}

Module Not Found in DLL

Add missing module to DLL entry:
entry: {
  vendor: ['react', 'react-dom', 'missing-module']
}

DLL Not Loading

Verify HTML includes DLL before app:
<script src="dll/vendor.dll.js"></script>
<script src="app.js"></script>

Best Practices

  • Rebuild DLL when dependencies change
  • Include only stable, frequently-used libraries
  • Use for development; consider alternatives for production
  • Automate DLL rebuilds in CI/CD
  • Document which libraries are in DLL