A pnpm-workspace monorepo for authoring userscripts with vite-plugin-monkey and Biome, distributed via Greasy Fork.
Node.js 26 and pnpm are declared in package.json devEngines with
onFail: "download", so pnpm fetches the matching versions on demand as well.
mise installThis installs the pinned toolchain; a mise postinstall hook then runs ni
to install the workspace dependencies. To install dependencies again later,
run ni directly.
nr newAnswer the prompts (name, display name, description, namespace, match patterns,
GM grants). A new package is created under packages/<name>/. Then run ni to
install its dependencies.
pnpm --filter <name> devVite starts a dev server and vite-plugin-monkey serves an install URL
(<name>.proxy.user.js). Install it once in your userscript manager
(Tampermonkey / Violentmonkey), then edits hot-reload live.
nr build # build all packages
pnpm --filter <name> build # build one packageEach package emits a single packages/<name>/dist/<name>.user.js with the
metadata banner and inlined dependencies.
The root
buildscript runspnpm -r build(all packages). To scope to one package, invoke pnpm's workspace filter directly:pnpm --filter <name> build.
nr checkEach package sets @version by hand in its vite.config.ts (SemVer, e.g.
1.0.0). Bump it to publish an update; leave it unchanged to ship code without
republishing — Greasy Fork treats an unchanged @version as a no-op.
On every push to main, the release workflow builds all packages and syncs
the resulting <name>.user.js files to the flat dist branch. Their raw URLs
https://raw.githubusercontent.com/simochee/userscripts/dist/<name>.user.js
are what each script's @downloadURL/@updateURL point at, and are registered
as the sync source on Greasy Fork. The workflow
commits to dist only when a build output actually changed.
When adding a new script, register it on Greasy Fork with its raw dist URL as
the sync source (optionally add the GitHub webhook for push-triggered sync).