Skip to main content
The webpack-dev-server provides a development server with live reloading and hot module replacement capabilities.

Installation

npm install --save-dev webpack-dev-server

Basic Configuration

webpack.config.js
module.exports = {
  devServer: {
    port: 3000,
    open: true,
    hot: true
  }
};

Dev Server Options

devServer.port
number
Port number for the dev server.
devServer: {
  port: 3000
}
Default: 8080
devServer.host
string
Host to use for the dev server.
devServer: {
  host: 'localhost' // or '0.0.0.0' for external access
}
Default: 'localhost'
devServer.hot
boolean | 'only'
Enable Hot Module Replacement.
devServer: {
  hot: true // enable HMR
  // or
  hot: 'only' // HMR without page reload as fallback
}
Default: true
devServer.open
boolean | string | object
Open the browser after server starts.
devServer: {
  open: true // default browser
  // or
  open: 'Chrome' // specific browser
  // or
  open: ['/home', '/about'] // multiple pages
}
Default: false
devServer.compress
boolean
Enable gzip compression for everything served.
devServer: {
  compress: true
}
Default: true

Static Files

devServer.static
boolean | string | object | array
Configure serving static files.
// Simple string
devServer: {
  static: './public'
}

// Object with options
devServer: {
  static: {
    directory: path.join(__dirname, 'public'),
    publicPath: '/assets',
    watch: true
  }
}

// Multiple directories
devServer: {
  static: [
    {
      directory: path.join(__dirname, 'public'),
      publicPath: '/assets'
    },
    {
      directory: path.join(__dirname, 'static'),
      publicPath: '/static'
    }
  ]
}

Proxy

devServer.proxy
object | array
Proxy API requests to another server.
devServer: {
  proxy: {
    '/api': 'http://localhost:3001',
    
    '/api/v2': {
      target: 'http://localhost:3001',
      pathRewrite: { '^/api/v2': '' },
      changeOrigin: true,
      secure: false
    },
    
    '/ws': {
      target: 'ws://localhost:3001',
      ws: true
    }
  }
}
Proxy options:
  • target: Target host
  • pathRewrite: Rewrite target’s URL path
  • changeOrigin: Change the origin header to the target URL
  • secure: Verify SSL certificates
  • ws: Proxy WebSockets
  • bypass: Function to bypass proxy conditionally

Headers and CORS

devServer.headers
object | function
Add custom headers to all responses.
devServer: {
  headers: {
    'X-Custom-Header': 'value'
  }
  // or function
  headers: () => {
    return {
      'X-Custom-Header': 'value'
    };
  }
}
devServer.allowedHosts
string | array
Whitelist hosts that are allowed to access the dev server.
devServer: {
  allowedHosts: [
    'host.com',
    '.host.com',
    'subdomain.host.com'
  ]
  // or
  allowedHosts: 'all' // allow all hosts
}

HTTPS

devServer.https
boolean | object
Enable HTTPS.
// Simple HTTPS
devServer: {
  https: true
}

// Custom certificates
devServer: {
  https: {
    key: fs.readFileSync('/path/to/server.key'),
    cert: fs.readFileSync('/path/to/server.crt'),
    ca: fs.readFileSync('/path/to/ca.pem')
  }
}

History API Fallback

devServer.historyApiFallback
boolean | object
Serve index.html for 404s (useful for SPAs).
// Simple
devServer: {
  historyApiFallback: true
}

// Advanced
devServer: {
  historyApiFallback: {
    rewrites: [
      { from: /^\/admin/, to: '/admin.html' },
      { from: /./, to: '/index.html' }
    ],
    disableDotRule: true
  }
}

Watch Options

devServer.watchFiles
string | array | object
Watch files and trigger full page reload.
devServer: {
  watchFiles: ['src/**/*.php', 'public/**/*']
  // or with options
  watchFiles: {
    paths: ['src/**/*.php'],
    options: {
      usePolling: false
    }
  }
}

Live Reload

devServer.liveReload
boolean
Enable live reload (disable if only using HMR).
devServer: {
  liveReload: true
}
Default: true

Client Configuration

devServer.client
object
Configure client-side behavior.
devServer: {
  client: {
    logging: 'info', // 'log' | 'info' | 'warn' | 'error' | 'none'
    overlay: {
      errors: true,
      warnings: false
    },
    progress: true,
    reconnect: true // or number of retries
  }
}

Advanced Options

devServer.devMiddleware
object
Options for webpack-dev-middleware.
devServer: {
  devMiddleware: {
    index: true,
    publicPath: '/assets/',
    serverSideRender: false,
    writeToDisk: false // or true or (filePath) => boolean
  }
}
devServer.server
'http' | 'https' | 'spdy' | object
Server type and options.
devServer: {
  server: 'https'
  // or
  server: {
    type: 'https',
    options: {
      key: fs.readFileSync('/path/to/server.key'),
      cert: fs.readFileSync('/path/to/server.crt')
    }
  }
}
devServer.setupMiddlewares
function
Add custom middleware.
devServer: {
  setupMiddlewares: (middlewares, devServer) => {
    devServer.app.get('/api/health', (req, res) => {
      res.json({ status: 'ok' });
    });
    return middlewares;
  }
}
devServer.webSocketServer
string | object
WebSocket server type.
devServer: {
  webSocketServer: 'ws' // or 'sockjs'
}

Common Patterns

Basic SPA Setup

webpack.config.js
module.exports = {
  devServer: {
    port: 3000,
    hot: true,
    open: true,
    historyApiFallback: true,
    compress: true
  }
};

API Proxy Configuration

webpack.config.js
module.exports = {
  devServer: {
    port: 3000,
    proxy: {
      '/api': {
        target: 'http://localhost:3001',
        changeOrigin: true,
        pathRewrite: { '^/api': '' }
      },
      '/auth': {
        target: 'http://localhost:3002',
        changeOrigin: true
      }
    }
  }
};

HTTPS Development

webpack.config.js
const fs = require('fs');

module.exports = {
  devServer: {
    https: {
      key: fs.readFileSync('path/to/key.pem'),
      cert: fs.readFileSync('path/to/cert.pem')
    },
    port: 8080
  }
};

Static Assets and Public Path

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

module.exports = {
  devServer: {
    static: [
      {
        directory: path.join(__dirname, 'public'),
        publicPath: '/'
      },
      {
        directory: path.join(__dirname, 'assets'),
        publicPath: '/assets'
      }
    ]
  }
};

Custom Headers and CORS

webpack.config.js
module.exports = {
  devServer: {
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
      'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization'
    }
  }
};

Development with WebSockets

webpack.config.js
module.exports = {
  devServer: {
    proxy: {
      '/api': 'http://localhost:3001',
      '/socket.io': {
        target: 'http://localhost:3001',
        ws: true
      }
    },
    client: {
      webSocketURL: 'ws://0.0.0.0:3000/ws'
    }
  }
};

Error Overlay Configuration

webpack.config.js
module.exports = {
  devServer: {
    client: {
      overlay: {
        errors: true,
        warnings: false,
        runtimeErrors: true
      },
      progress: true
    }
  }
};

Running the Dev Server

# Using npm scripts
npm run serve

# Using npx
npx webpack serve

# With specific config
npx webpack serve --config webpack.dev.js

# With mode
npx webpack serve --mode development

# With custom port
npx webpack serve --port 3000
Package.json script:
package.json
{
  "scripts": {
    "start": "webpack serve --mode development --open",
    "serve": "webpack serve --config webpack.dev.js"
  }
}