| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
A Vite plugin for developing and building Tampermonkey, Greasemonkey and Violentmonkey userscripts.
Requires Vite 8 and Node >=22.
pnpm add vite-userscript-plugin -Dimport { defineConfig } from 'vite'
import userscript from 'vite-userscript-plugin'
import pkg from './package.json' with { type: 'json' }
export default defineConfig({
plugins: [
userscript({
entry: 'src/index.ts',
header: {
name: pkg.name,
version: pkg.version,
match: [
'https://example.com/',
'https://example.org/'
]
}
})
]
}){
"scripts": {
"dev": "vite",
"build": "vite build"
}
}Add types: Vite, one manager (tampermonkey, greasemonkey, or violentmonkey), and the virtual module.
src/vite-env.d.ts:
/// <reference types="vite/client" />
/// <reference types="vite-userscript-plugin/types/tampermonkey" />
/// <reference types="vite-userscript-plugin/virtual" />Or tsconfig.json:
{
"compilerOptions": {
"types": [
"vite/client",
"vite-userscript-plugin/types/tampermonkey",
"vite-userscript-plugin/virtual"
]
}
}Details: types/README.md.
vite prints /{fileName}.dev.user.js — install that URL once. HMR covers code and styles.
Important
Changing @match, @grant, or @name needs a reinstall.
vite build writes {fileName}.user.js to dist/.
Pass an array of configs. Each item is one full script — no shared header.
See examples/multiple-entries.
CSS from imports and SFC <style> (Vue, Svelte) is collected and injected into the userscript.
import './style.css'Note
Do not put userscript assets in public/ — those URLs hit the host site and 404. Import the file so Vite inlines it.
index.html is a normal Vite app next to the userscript. vite serves it at /. vite build writes it to dist/ beside {fileName}.user.js.
Warning
Keep the page's <script> entries distinct from entry.
Script metadata: import virtual:vite-userscript-plugin (name, version, file).
See examples/sourcemap.
vite build writes {fileName}.user.js and {fileName}.meta.js. index.html is written too, when present.
Minify is off (build.minify). Sourcemaps are inlined into .user.js when build.sourcemap is on.
See examples/sourcemap.
userscript(config) or userscript([config, config, …]). Options are not shared across the array.
| Option | Default | Description |
|---|---|---|
| entry | — | Userscript entry. Required. |
| header | — | Metablock. Required: name, version, match. |
| fileName | sanitized header.name | Output base name ({fileName}.user.js). |
| server.open | false | Open the .dev.user.js install URL when Vite starts. |
| server.prefix | 'server:' | Prefix for @name in serve mode. false disables it. |
| cssInject | 'auto' | How production CSS is injected. 'auto' uses GM_addStyle or a <style> node. |
| align | 1 | Extra spaces after the longest @key. false — one space. |
| generate | — | Rewrite the generated metablock. |
| autoMetaUrls | false | Fill empty updateURL / downloadURL from homepage / homepageURL / website / source. |
| metaFile | true | Emit {fileName}.meta.js. |
Everything else on header follows the manager metablock (@grant, @require, @connect, …).
In serve mode the header lists every grant. In production the plugin scans the bundle and writes only the grants in use. grant: "none" disables GM APIs and is never mixed with the scan.
Warning
Keep metaFile: true if you use autoMetaUrls. Otherwise @updateURL points at a file that is not emitted.
| Example | What it shows |
|---|---|
| basic | Vanilla + SCSS. |
| react | JSX, CSS, React refresh. |
| vue | SFC <style>, minify, sourcemap. |
| svelte | SFC <style>. |
| multiple-entries | Two scripts. |
| sourcemap | Inline map, HTML page, virtual module. |
Warning
The host page can block Vite modules from localhost. Use a CSP-disable extension, or a browser profile without the site CSP.
Warning
https://example.com will not load http://localhost:5173. Serve Vite over HTTPS: vite-plugin-mkcert before userscript(), or server.https.
Note
Userscripts run on someone else’s origin. Import the file so Vite inlines it. public/ only works for the index.html app on the Vite origin.
Note
Serve injects type="module" (async). Production is a synchronous IIFE unless you use top-level await.
| v1 | v2 |
|---|---|
| vite build --watch | vite |
| esbuildTransformOptions | removed |
| server.port | Vite server.port |
| minify on by default | off; set build.minify |
| *.proxy.user.js + file:// | *.dev.user.js from Vite |
| Vite 3–7 | Vite 8 |
| scripts + shared header | userscript([config, config, …]) |
| ScriptOptions | removed |
| Back | FazBrowse Home | New Git URL |