Make your own plugin for UnderScript. You don't need to know how to program to get started.
Prefer to be asked? The command-line generator lets you set up a plugin by answering a few questions.
Or use the web generator to fill out basic details and get a plugin you can use in seconds.
- Install UnderScript and a userscript manager like Tampermonkey
- In Chrome, Edge and Opera, let Tampermonkey run userscripts, or none of them will load:
- Right-click the Tampermonkey icon and choose "Manage extension"
- If there's an "Allow User Scripts" toggle, turn it on
- If there isn't one, turn on "Developer mode" at the top right of
chrome://extensions(edge://extensions,opera://extensions) - If scripts stop running after you change either setting, turn "Allow User Scripts" off and on again
- Open my-plugin.user.js and copy everything in it
- In Tampermonkey, create a new script and paste it over what's there, then save
- Reload undercards, you should see a "Hello from my plugin!" toast
Change these in the file, they're all near the top:
@name,@description,@author,@namespacein the header: what Tampermonkey shows for your script@version: raise it every time you publish a change- The name in
underscript.plugin('My Plugin', ...): what UnderScript shows for your plugin. At most 20 characters, only letters, numbers and spaces, and no two plugins can share a name - The settings and the code inside
:preload: replace the example with your own
Comments in the file explain each part. When you want to do more, the Plugin API docs list everything a plugin can do.
Put your file somewhere public, like a GitHub repository or a gist, and add these two lines to the header with the link to the raw file:
// @updateURL https://example.com/my-plugin.user.js
// @downloadURL https://example.com/my-plugin.user.jsTampermonkey will then offer the new version whenever you raise @version.
UnderScript has a "Community Plugins" menu where players can find and install plugins. To get yours listed, open a pull request to UnderScript that adds an entry to plugins.json:
{
"name": "My Plugin",
"author": "Your Name",
"updateURL": "https://example.com/my-plugin.user.js"
}name must be exactly the name you pass to underscript.plugin().
If you want a proper project, with a bundler, editor autocomplete and automatic releases, the project template is at the root of this repository. Click "Use this template" on GitHub to start your own copy.
Or run the command-line generator, which turns a few questions into either a single script file or a full project and leaves out whatever you decline:
npx github:UCProjects/Plugin-Generator- Install Node.js 24 (20.19 and 22.13 or newer also work)
- Edit package.json:
name(the file name),displayName(the plugin name, at most 20 characters of letters, numbers and spaces),description,author,repository(owner/repo) andhomepage - Run
npm install - Edit code in index.js
npm start: rebuilddiston every changenpm run build: builddist/<name>.user.jsanddist/<name>.meta.jsnpm run lint: check the code stylenpm run check: type check against the UnderScript APInpm run types: download the latest UnderScript type definitions intotypes, this also happens onnpm install
The userscript header is generated from package.json, so there is nothing to keep in sync by hand.
Tampermonkey can load the file you build straight from your disk, so you don't have to paste it in after every change.
-
Make sure Tampermonkey can run userscripts, as in the quick way
-
Allow Tampermonkey to access file URLs: in your browser's extensions page, open Tampermonkey's details and turn on "Allow access to file URLs"
-
In Tampermonkey, create a new script and replace everything in it with the following, using the real path to your
distfolder (on Windows it looks likefile:///C:/Users/you/my-plugin/dist/my-plugin.user.js):// ==UserScript== // @name My Plugin (dev) // @match https://*.undercards.net/* // @exclude https://*.undercards.net/*/* // @grant none // @require https://raw.githubusercontent.com/UCProjects/UnderScript/master/src/checkerV2.js // @require file:///path/to/my-plugin/dist/my-plugin.user.js // ==/UserScript==
-
Run
npm start, then reload undercards whenever it has rebuilt
Things to know:
- Tampermonkey only reads the header of the small script above, not the one in
dist. If you change tags inpackage.json, copy them fromdist/<name>.meta.jsinto the dev script by hand - Turn off any installed copy of the same plugin while you test, because two plugins can't share a name
- Your plugin needs UnderScript installed and turned on, the same as for players
Add any userscript tag to the userscript object in package.json. Use a list when you need the same tag more than once:
"userscript": {
"require": ["https://unpkg.com/lodash@4.17.21/lodash.min.js"],
"run-at": "document-body",
"grant": ["GM_xmlhttpRequest", "GM_getValue"],
"connect": "api.example.com"
}match,excludeandrequireare added after the defaults. The defaultrequireis the UnderScript check, which shows players a friendly message when UnderScript is missinggrantreplaces the default, which isnonenamespace,updateURLanddownloadURLare built fromrepository, set them yourself to point somewhere else, or setupdateURLanddownloadURLtofalseto leave them out- Every other tag is added as written
name,description,version,authorandhomepagecome from the fields at the top ofpackage.json, and the build tells you if you set them inuserscript
Without a repository, namespace, updateURL and downloadURL are left out.
- Run
npm version patch(orminor,major), this updates the version and creates a tag - Run
git push --follow-tags
GitHub builds the plugin and publishes <name>.user.js and <name>.meta.js to a release. Players install from, and get updates from, the latest release.
Don't want GitHub releases? Delete release.yml, run npm run build, and host the files in dist wherever you like. Point updateURL and downloadURL at them in userscript (see above) so players still get updates.