Webpack Userscript Plugin
raw JSON → 3.2.3 verified Sat May 09 auth: no javascript
A webpack plugin for building userscript projects targeting Tampermonkey, Greasemonkey, Violentmonkey, and similar userscript engines. Current stable version is 3.2.3 (Dec 2024), with active maintenance on GitHub. The plugin automatically generates userscript headers from metadata, produces .meta.js files for update checks, and creates proxy scripts to avoid caching during development. Key differentiators: full TypeScript support since v3, multi-entry support, header interpolation, and integrated hot-reload workflow with webpack-dev-server. Requires webpack 5 as a peer dependency.
Common errors
error TypeError: Cannot read properties of undefined (reading 'chunkName') ↓
cause In v3.2.3 and earlier, the interpolater fails when chunk name is empty string.
fix
Upgrade to v3.2.3 which fixes the bug. Alternatively, ensure at least one chunk is named.
error Error: Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. ↓
cause Using `WebpackUserscript` (old constructor) instead of `UserscriptPlugin` in v3.
fix
Use
const { UserscriptPlugin } = require('webpack-userscript') and instantiate with new UserscriptPlugin({...}). error Module parse failed: Unexpected token (1:0) - You may need an appropriate loader to handle this file type. ↓
cause The entry file is not recognized as valid JavaScript (e.g., missing `.js` extension).
fix
Ensure your entry file has a
.js or .user.js extension and is valid JavaScript/TypeScript. error Cannot find module 'webpack-userscript' ↓
cause The package is not installed or node_modules is missing.
fix
Run
npm install webpack-userscript --save-dev or yarn add webpack-userscript --dev. error UserscriptPlugin is not a constructor ↓
cause Importing the default export instead of named export in ESM context.
fix
Use
import { UserscriptPlugin } from 'webpack-userscript' (named import) instead of default import. Warnings
breaking In v3.0.0, the plugin constructor was renamed from `WebpackUserscript` to `UserscriptPlugin`. Old code using `new WebpackUserscript()` will throw a ReferenceError. ↓
fix Change `const WebpackUserscript = require('webpack-userscript'); new WebpackUserscript(...)` to `const { UserscriptPlugin } = require('webpack-userscript'); new UserscriptPlugin(...)`.
breaking In v3.0.0, the plugin was rewritten in TypeScript. CommonJS require of the default export no longer works; use named export `UserscriptPlugin`. ↓
fix Use `const { UserscriptPlugin } = require('webpack-userscript');` instead of `const UserscriptPlugin = require('webpack-userscript');`.
deprecated The `headers.proxyScript` option was deprecated in v3.2.0; use `proxyScript` directly in the plugin options instead. ↓
fix Move `headers.proxyScript` to the top-level `proxyScript` option in `new UserscriptPlugin({ proxyScript: { ... } })`.
gotcha When using `metajs: true`, the generated .meta.js file does not include the script body. Tampermonkey may fail update checks if the script is not hosted at the expected URL. ↓
fix Ensure the output .meta.js file is served at the URL specified by `@updateURL` header. Use `headers.updateURL` to set it correctly.
gotcha If the entry file does not end with `.user.js`, the plugin will not prepend headers. Headers are only added to entry points whose names match `*.user.js`. ↓
fix Rename your entry file to end with `.user.js`, e.g., `./src/index.user.js`.
Install
npm install webpack-userscript yarn add webpack-userscript pnpm add webpack-userscript Imports
- UserscriptPlugin wrong
const WebpackUserscript = require('webpack-userscript');correctconst { UserscriptPlugin } = require('webpack-userscript'); - UserscriptPlugin wrong
import UserscriptPlugin from 'webpack-userscript';correctimport { UserscriptPlugin } from 'webpack-userscript'; - UserscriptOptions wrong
import { UserscriptOptions } from 'webpack-userscript';correctimport type { UserscriptOptions } from 'webpack-userscript';
Quickstart
const path = require('path');
const { UserscriptPlugin } = require('webpack-userscript');
module.exports = {
entry: './src/index.user.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
},
plugins: [
new UserscriptPlugin({
headers: {
name: 'My Userscript',
namespace: 'https://example.com',
version: '1.0.0',
description: 'A sample userscript built with webpack',
author: 'You',
match: 'https://example.com/*',
grant: 'none',
},
metajs: true,
proxyScript: {
baseURL: 'http://localhost:8080',
},
}),
],
mode: 'development',
};