Automatically convert Tampermonkey/GreaseMonkey scripts into Chrome Extensions (Manifest V3).
- Zero Friction for Users: Install directly from the Chrome Web Store—no Tampermonkey required.
- Ecosystem Benefits: Native discovery, established trust, and automatic updates.
- Broader Reach: Cross-platform distribution with trackable analytics.
Prepare the userscript and store assets; an agent builds and packages on your machine. You finish Web Store listing and review once the ZIP is ready.
Your .js must include:
// ==UserScript==
// @name Extension Name
// @version 1.0.0
// @description Description (Required for Web Store)
// @match https://example.com/*
// ==/UserScript==Recommended: @namespace, @author, @license, @grant (default none), @require, @run-at, @inject-into / @world.
This tool is a Web Store packaging pipeline with best-effort GM polyfills—not a full Tampermonkey runtime.
| Path | Best for | Notes |
|---|---|---|
| Recommended | @grant none + DOM / localStorage |
Closest to extension content scripts |
| GM polyfills | @grant GM.* |
Best-effort; see table below |
| Page JS objects | CodeMirror, window.App, etc. |
@inject-into page or @world MAIN |
| Metadata | Chrome content_scripts.world |
Use when |
|---|---|---|
(default) / @inject-into content / @world ISOLATED |
ISOLATED |
chrome.* / GM polyfills |
@inject-into page / @world MAIN |
MAIN |
Page JS objects |
MAIN cannot use chrome.*. Do not combine MAIN with GM grants that need storage / tabs / XHR.
GM_setValue / GM_getValue / GM.deleteValue / GM.listValues return Promises (not sync):
const x = await GM_getValue('k', 0);For sync state, use @grant none and localStorage.
Both GM_xxx and GM.xxx @grant styles are accepted.
| GM API | Polyfill Strategy |
|---|---|
GM_addStyle / GM.addStyle |
Injects <style> |
GM.setValue / getValue … |
Async chrome.storage.local |
GM.xmlHttpRequest |
Background fetch() (+ host_permissions / @connect) |
GM.notification |
chrome.notifications |
GM.setClipboard |
navigator.clipboard + fallback |
GM.openInTab |
chrome.tabs.create |
GM.download |
chrome.downloads.download |
Not supported (or only warned): unsafeWindow, @resource / GM_getResource*, sync GM_getValue, binary XHR responseType, XHR abort across contexts.
In the script project’s store_assets/:
icon.png(source; tool generates 16/48/128)- 1–5 screenshots (
.png/.jpg)
- Name ≤ 75 chars; description required ≤ 132 chars; SemVer
x.y.zrecommended - Prefer specific
@matchover<all_urls>for review speed - Remote
@requiremust comply with Store policies - One-time ~$5 Chrome Web Store developer fee
- After the ZIP exists, submit listing text, privacy form, and screenshots in the developer console
Created by Victor42 & Agent Vik
Convert a Tampermonkey userscript folder into a Manifest V3 Chrome extension, and operate the CLI for rebuilds/packaging when asked.
- Python 3 with pip
- Network access the first time you resolve
@requireURLs (or a warm dependency cache) - A target project folder that already contains a
.jsfile with a// ==UserScript==header
- Clone or locate this repo. From the repo root:
pip install -r requirements.txt- Confirm the target folder layout:
project_root/
├── script.js # must include ==UserScript==
└── store_assets/
├── icon.png # required for packaging / store
└── screenshot*.png # 1–5 for --package / Web Store
Primary entrypoint: python build.py SCRIPT_DIR.
Flags:
- (none) — build into
SCRIPT_DIR/extension/ --clean— deleteextension/then rebuild-v/--verbose— verbose logs--package— ZIP + open upload URLs fromstore_assets/upload_config.json--refresh-dependencies— re-download@requiredeps (ignore verified cache)
Typical flows:
- Build once:
python build.py /path/to/project_root→ verifyextension/manifest.jsonexists. - Local load test: tell the human to open
chrome://extensions→ Developer mode → Load unpacked →extension/. - Iterate after script edits: rebuild (add
--cleanif polyfills/deps look stale). - Publish packaging:
python build.py /path/to/project_root --package, then stop—store listing is human.
Auto-detection: any .js under script_dir with // ==UserScript== is used; do not invent metadata.
- Approving Load unpacked / Tampermonkey prompts
- Web Store account, privacy questionnaire, screenshots copy, publish review
- Ongoing use of the resulting extension
- Do not invent missing
@name/@description/@match; fix or ask - Do not commit dependency caches as secrets; do not embed API keys
- Product contracts / architecture:
notes.md