Plugins let you run your own web app inside 5Stack. Same sidebar, same header, same theme, same login. Your app is not part of 5Stack and does not require a fork or a rebuild of the panel.
Technically, a plugin is a Vue Module Federation
remote. The panel loads it at runtime and mounts it on a native route,
/apps/<slug>.
- No iframe. Your component runs inside the panel's own Vue app, sharing its Vue instance, its router, and its styling.
- No second login. The panel hands you the authenticated user. If you have a backend. It exchanges the session cookie the browser already sends for a verified identity, instead of running its own Steam OpenID flow.
- Native look. The shared
@5stack/uiTailwind preset and design tokens mean your UI follows the operator's live branding automatically. - No panel rebuild. Plugins live in a database registry. An admin adds a URL; the panel picks it up.
::: warning Panel plugins, not game plugins This section is about extending the panel's web UI. If you are looking to run SwiftlyS2 or CounterStrikeSharp plugins on a game server, see Game Plugin Runtimes and Custom Game Plugins instead. :::
-
You build a Vue app with Vite and expose your root component as a Module Federation remote. The build emits
dist/assets/remoteEntry.js. -
You ship a manifest,
5stack-plugin.json, at the root of that same build. -
You host
dist/somewhere the panel's users can reach. -
An admin pastes your URL into Settings → Application → Plugins, hits Detect, and enables it.
-
The panel writes a row into its plugin registry. Every connected client picks the new entry up over a live subscription, renders a sidebar item, and, when a user navigates to
/apps/<slug>, fetches yourremoteEntry.js, resolves your exposed module, and mounts it:<component :is="RemoteComponent" :user="authStore.me" :base="base" :path="path" :query="query" :navigate="navigate" />
Those props are the entire inbound contract: who is signed in, where you are mounted, and a way to move around. Everything else your plugin needs. It fetches itself. See Routing for what each one carries.
| You get | You don't get |
|---|---|
A full page at /apps/<slug> |
Hooks into match pages, settings tabs, or arbitrary host slots |
| A sidebar nav entry with your icon | Control over where in the nav it appears |
The logged-in user (steam_id, name, role) |
The host's Apollo/GraphQL client or Hasura session |
Role-gated visibility via requiredRole |
A sandbox, your code runs with full access to the page |
| The design tokens + Tailwind preset | A ready-made component library (see Components) |
There is exactly one extension point: the whole-page mount. There is no slot
system. If you need data from 5Stack. You either read it off the user prop or
you call your own backend.
::: info No sandbox
A plugin is loaded into the panel's JavaScript context with no isolation. It can
reach into the host's stores and act as the logged-in user against any API the
panel can reach, and its backend receives that user's live session cookie. (The
cookie itself is httpOnly, so plugin JavaScript cannot read it directly, but
that is a small consolation given everything else it can do.) requiredRole
controls who
sees the page, not what the code can do. There is also no integrity pinning
on remoteEntry.js. The panel loads whatever the registered URL serves, so a
compromised plugin host compromises the panel for every user until the page is
disabled. Only install plugins you trust, and tell your users the same about
yours.
:::
| Repo | What it shows |
|---|---|
| 5stack-example-plugin | The smallest complete plugin. Start here, copy it. |
| 5stack-inventory-plugin | A production plugin with a Fastify backend, Postgres, session-cookie auth, and a Kubernetes deployment. |
- Getting Started, scaffold, build, and register a plugin in about ten minutes.
- The Manifest, every
5stack-plugin.jsonfield. - Routing, the inbound props, deriving screens from the URL, and mounting as a tab on player profiles.
- Module Federation, the Vite config and the shared-singleton rules that make or break a plugin.
- Styling, Tailwind setup, design tokens, and the CSS pitfalls unique to runtime-injected styles.
- Components, what
@5stack/uiactually gives you today. - Backend & Auth, verifying identity and talking to your own API.
- Deploying, hosting, CORS, caching, and registration.