The catalog behind the 5Stack plugin directory. Every 5Stack panel polls the
index this repo publishes and renders it at /plugins, so adding a plugin here
makes it one-click installable on every install in the world.
Published to https://registry.5stack.gg/ by GitHub Pages, rebuilt
hourly so new upstream plugin releases appear on their own. A build only
deploys when what it produced differs from what the site already serves, so
generated_at in the index marks the last time the catalog actually changed,
not the last time the cron ran. A manual run of the workflow has a force
option to redeploy regardless.
The custom domain lives in the root CNAME, which the build copies into dist/
— the published artifact is the site root, so the domain has to travel with it.
Two different things are called "plugin" in 5Stack, and both live here:
kind | What it is | Installed by |
|---|---|---|
panel | A web app that mounts as a native page at /apps/<slug> | ./plugin.sh <repo> on the panel host |
game | A CS2 server plugin (SwiftlyS2 or CounterStrikeSharp) that loads into the game server | The panel, into each node's plugin store |
bundle | One project shipping both halves itself | Both of the above |
Most things that feel like a pair are not a bundle. 5Stack Inventory is a
panel plugin that names the CS2 Inventory Simulator in pairs_with and
describes how it configures it in wiring — the game plugin is somebody else's
project with its own entry, and republishing its releases would list the same
download twice under two names. Reach for bundle only when one repo genuinely
ships both halves.
- Drop a JSON file in
registry/<kind>/<slug>.json. The filename must match the slug. Start fromregistry/game/inventory-simulator.json. npm run validate.- Open a PR.
verified: trueis set during review, not by the submitter — it is the only thing telling an operator a maintainer actually looked at the plugin.
Never write a versions array. CI resolves it from the upstream repo's
GitHub releases on every build, pinning each asset's URL and SHA-256 so a panel
can verify what it downloads. Hand-written versions are rejected by the validator.
5Stack game servers are Linux containers (steamrt sniper). The build filters release assets accordingly:
- an asset naming another platform (
windows,win64,osx,darwin) is never selected, and the validator rejects a glob that names one; - where a project ships one asset per platform, the Linux one is chosen rather than whichever GitHub returns first;
- a release that publishes only non-Linux assets is skipped with a warning.
An asset that names no platform at all (a portable .NET zip, which is what most CS2 plugins ship) is taken as-is.
layout tells the installer how to unpack the release asset:
csgo(default) — the archive root isgame/csgo, so it already containsaddons/.... This is what the inventory simulator ships.plugin— the archive root is the plugin folder itself. Setinstall_path(e.g.addons/{runtime}/plugins/MyPlugin) and the installer places it there.{runtime}expands toswiftlys2orcounterstrikesharp.
Both frameworks ship FollowCS2ServerGuidelines: true, which blocks the calls a
plugin needs to change what a player sees — custom HUDs, scoreboard text, rank
badges. A plugin that cannot work without those calls declares:
"requires_server_guidelines_disabled": trueValve's position is that this can get every GSLT on the server owner's Steam account banned, so the panel never flips it on the strength of the registry alone: the flag only surfaces a per-install opt-in, off by default, next to that warning. Set it when the plugin genuinely does not function otherwise, not when it merely has a nicer HUD if you do.
A CounterStrikeSharp plugin will not load under SwiftlyS2 and vice versa, so a
game plugin declares one variants entry per runtime it actually ships. A plugin
with only a counterstrikesharp variant simply won't be offered on a SwiftlyS2
deployment (unless that deployment runs the CSS compatibility layer).
npm run validate # schema + cross-entry checks, no network
npm run build # resolves releases and writes dist/index.json
node scripts/changed.mjs # says whether dist/ differs from the live registrybuild hits the GitHub API. Set GITHUB_TOKEN to avoid the unauthenticated
rate limit.
An operator can mirror or fork this registry and point their panel at it:
Settings → Application → Game Plugins → Registry URL, or the
public.plugin_registry_url setting.