A collection of user scripts for various websites, built with TypeScript and managed as a monorepo.
This repository uses a monorepo structure with the following setup:
- Yarn workspaces for package management
- NX for build orchestration
- TypeScript for development
- mise for toolchain (node/yarn) version management
- release-it for per-package version management
- oxlint for linting
- GitHub Actions for CI/CD
-
Install the pinned toolchain with mise (this installs the node and yarn versions pinned in
mise.toml):mise install
-
Install dependencies:
yarn install
-
Build the project:
yarn build
- Each script is a separate package in the
packages/directory. - To add a new script, copy
packages/template/topackages/<your-script>/and update itspackage.jsonname andsrc/meta.json. Set"greasyforkPublish": truein itspackage.jsonto opt it into the release pipeline; leave the field off for an internal-only script. - A script's
// ==UserScript==metadata block is not written intosrc/index.ts. It lives in that package'ssrc/meta.json, andscripts/build-userscript.mjsrenders it intodist/script.user.jsat build time with@versiontaken from the package'spackage.json.
- Every publishable package owns its own version (
package.json) and its ownCHANGELOG.md. There is no repo-wide version. - Versions are bumped automatically on merge to
main, never in a PR. A PR gets a sticky comment previewing the bumps it will cause. - A patch bump is applied to each package whose files changed since the last release. Bumping a version by hand in a PR (e.g. for a minor or major release) is respected and not bumped again on top.
- Each release run publishes one GitHub Release carrying every bumped script's
compiled
<package-name>.user.jsas an asset. Published scripts point their@downloadURL/@updateURLat that release's stablelatest/downloadURL, so a userscript manager installed directly from GitHub auto-updates from there. GreasyFork forcibly rewrites those same fields for any script actually listed on its site, so the existing GreasyFork listings keep updating through GreasyFork's own mechanism instead - this pipeline doesn't change that. yarn bumpruns the same bump logic locally; pass--previewto see what would happen without writing anything.
MIT