Skip to main content

DotenvPlugin

The DotenvPlugin loads environment variables from .env files and makes them available during the build process. It supports multiple .env files based on the build mode and provides a flexible templating system.
This is a built-in alternative to the popular dotenv-webpack package. It’s available in webpack 5.74.0+.

Basic Usage

const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.DotenvPlugin()
  ]
};
With default settings, this loads variables from .env files with the WEBPACK_ prefix.

Configuration Options

path
string
Path to the directory containing .env files.Default: Project root directory
template
string[]
Template array for .env file names. [mode] is replaced with the current mode.Default: [".env", ".env.local", ".env.[mode]", ".env.[mode].local"]
prefix
string | string[] | function
Prefix(es) for environment variables to include.Default: "WEBPACK_"
  • String: Variables must start with this prefix
  • Array: Variables must start with any of these prefixes
  • Function: (key) => boolean to determine if variable should be included
allowEmptyValues
boolean
default:"false"
Allow empty values for environment variables.
systemvars
boolean
default:"false"
Load system environment variables.
defaults
object
Default values for environment variables.

File Loading Order

The plugin loads .env files in this order (later files override earlier ones):
  1. .env
  2. .env.local
  3. .env.[mode] (e.g., .env.production)
  4. .env.[mode].local (e.g., .env.production.local)
Add .env*.local files to .gitignore to keep sensitive values out of version control.

Examples

Custom Prefix

Only load variables with a specific prefix:
new webpack.DotenvPlugin({
  prefix: 'APP_'
})
.env:
APP_API_URL=https://api.example.com
APP_VERSION=1.0.0
OTHER_VAR=ignored  # Won't be loaded (no APP_ prefix)

Multiple Prefixes

Load variables with multiple prefixes:
new webpack.DotenvPlugin({
  prefix: ['APP_', 'PUBLIC_']
})
.env:
APP_API_URL=https://api.example.com
PUBLIC_URL=/
PRIVATE_KEY=secret  # Won't be loaded

Custom Filter Function

Use a function for complete control:
new webpack.DotenvPlugin({
  prefix: (key) => {
    // Only load variables ending with _URL or _KEY
    return key.endsWith('_URL') || key.endsWith('_KEY');
  }
})

Mode-Specific Files

Different values for development and production: .env:
WEBPACK_API_URL=https://api.example.com
.env.development:
WEBPACK_API_URL=http://localhost:3000
WEBPACK_DEBUG=true
.env.production:
WEBPACK_API_URL=https://api.production.com
WEBPACK_DEBUG=false
When building with --mode production, production values override defaults.

System Variables

Include system environment variables:
new webpack.DotenvPlugin({
  systemvars: true,
  prefix: 'WEBPACK_'
})
This allows you to set variables like WEBPACK_API_URL=https://api.com npm run build.

Default Values

Provide fallback values:
new webpack.DotenvPlugin({
  defaults: {
    WEBPACK_API_URL: 'http://localhost:3000',
    WEBPACK_TIMEOUT: '5000'
  }
})

Custom Directory

Load .env files from a specific directory:
new webpack.DotenvPlugin({
  path: path.resolve(__dirname, 'config')
})

Custom Template

Use custom .env file naming:
new webpack.DotenvPlugin({
  template: [
    '.env',
    '.env.[mode]',
    '.env.override'
  ]
})

Using Loaded Variables

Variables are available through process.env:
// In your application code
console.log(process.env.WEBPACK_API_URL);

// In webpack config
module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      'process.env.API_URL': JSON.stringify(process.env.WEBPACK_API_URL)
    })
  ]
};
DotenvPlugin loads variables during webpack configuration. Use DefinePlugin to make them available in your application code.

Complete Example

Project structure:
my-app/
├── .env
├── .env.local
├── .env.production
├── .gitignore
├── webpack.config.js
└── src/
    └── index.js
.env:
WEBPACK_APP_NAME=My App
WEBPACK_API_URL=https://api.example.com
.env.local:
WEBPACK_API_URL=http://localhost:3000
.env.production:
WEBPACK_API_URL=https://api.production.com
WEBPACK_ANALYTICS_ID=UA-123456
.gitignore:
.env*.local
webpack.config.js:
const webpack = require('webpack');

module.exports = (env, argv) => ({
  plugins: [
    new webpack.DotenvPlugin({
      prefix: 'WEBPACK_',
      defaults: {
        WEBPACK_API_URL: 'http://localhost:3000'
      }
    }),
    new webpack.DefinePlugin({
      APP_CONFIG: JSON.stringify({
        name: process.env.WEBPACK_APP_NAME,
        apiUrl: process.env.WEBPACK_API_URL,
        analyticsId: process.env.WEBPACK_ANALYTICS_ID
      })
    })
  ]
});
src/index.js:
console.log('App Config:', APP_CONFIG);
// Development: { name: 'My App', apiUrl: 'http://localhost:3000', analyticsId: undefined }
// Production: { name: 'My App', apiUrl: 'https://api.production.com', analyticsId: 'UA-123456' }

vs. EnvironmentPlugin

FeatureDotenvPluginEnvironmentPlugin
Loads .env files✅ Yes❌ No
Mode-specific files✅ Yes❌ No
System env varsOptional✅ Always
Prefix filtering✅ Yes❌ No
Default values✅ Yes✅ Yes
Use DotenvPlugin for .env file support, EnvironmentPlugin for simple system variable injection.