VRCNext Plugins
Build plugins for VRCNext — without modifying VRCNext.
VRCNext ships no plugin API. The
plugin system adds one by installing
itself as a VRCNext custom theme: a folder under ~/.config/VRCNext/custom-themes/ whose
JavaScript VRCNext injects into its own page. That folder lives in the config directory, not the
install tree, so app updates leave it alone.
The page runs one static bundle containing the host and every installed plugin. The
VRCNext Bridge, a small native daemon, produces it: it clones plugin repositories
over HTTPS with pure-Rust git, checks them, and runs a pinned esbuild. The page never evaluates
code at runtime and never fetches anything on its own. Without the bridge there is no install,
no state and no build — it is mandatory, and the installer sets it up in one command.
Users install a plugin by pasting its repository URL into the Plugins tab. One repository is
one plugin: plugin.json and main.ts at the root.
Thirty-second version
import { definePlugin, type PluginId } from '@vrcnext/plugin-api';
export default definePlugin({
id: 'my-plugin' as PluginId,
activate(ctx) {
ctx.gameLog.onType('gl_player_join', (entry) => {
ctx.notifications.toast({ message: `${entry.message} joined.` });
});
},
});
Put that in main.ts, declare "permissions": ["gamelog"] in plugin.json, push, and paste
the repository URL into the Plugins tab. The bridge compiles it; nothing is built on your side.
What plugins can do
| Capability | API | Permission |
|---|---|---|
| VRCNext host events, verified payloads typed | ctx.events |
host:events |
| Backend actions, with request/response | ctx.bridge |
host:actions |
| Observe or drop the actions VRCNext sends | ctx.bridge.interceptOutbound |
host:intercept |
Outbound HTTP — the only fetch a plugin has |
ctx.http |
network |
| VR overlay and desktop notifications through the bridge (any platform) | ctx.native |
native |
| OSC send and receive — through VRCNext on Windows, through the bridge on Linux | ctx.osc |
osc |
| VRChat game log stream and backlog | ctx.gameLog |
gamelog |
| In-app toasts and confirm modals; OS tray + SteamVR overlay (Windows only) | ctx.notifications |
notifications |
| Context-menu items, dividers and submenus | ctx.contextMenu |
context-menu |
| In-page HTTP routes with path parameters | ctx.router |
routes |
| Clipboard read and write | ctx.clipboard |
clipboard |
| Deep links VRCNext delivers | ctx.deepLinks |
host:events (openDeepLink) |
Sidebar tabs, dashboard cards, settings cards, custom CSS, ui.kit |
ctx.ui |
none |
| Typed, persisted, schema-rendered settings, including pickers over VRCNext’s own data | ctx.settings |
none |
| Reading users, avatars, worlds, groups and your instance without opening a dialog | ctx.vrchat |
vrchat |
| Levelled logging with a live in-app panel | ctx.logger |
none |
Documentation
Using VRCNext plugins
| Page | What it covers |
|---|---|
| Installer | The one-line install, what it sets up, its flags, and how to remove it again. |
| Using plugins | Finding, installing, enabling, updating and removing a plugin — and what to check when one misbehaves. |
Writing one — start here
| Page | What it covers |
|---|---|
| Getting started | The one-line install, pairing, your first plugin from the template. |
| Plugin anatomy | The flat repository, definePlugin, lifecycle, disposal, the context object. |
| plugin.json | Every manifest field and its rules. |
| Permissions | Declared categories, first-use prompts, what the user sees. |
| Source policy | What the bridge refuses to compile, and why. |
| Settings | Declarative schema, type inference, persistence. |
Capabilities
| Page | What it covers |
|---|---|
| Events & actions | Host events, sending actions, interception. |
| UI injection | Nav tabs, dashboard cards, settings cards, CSS, the kit. |
| Notifications | In-app, desktop tray, SteamVR overlay, confirm modals; VR and desktop via the bridge. |
| VRCNext Bridge | What the daemon does, pairing, status, ctx.native. |
| Context menus | Items, dividers, submenus, entity targets. |
| OSC | Sending and receiving OSC — through VRCNext, or through the bridge where VRCNext has none. |
| Game log | The VRChat log stream and backlog. |
| VRChat data | Friends, favourites, groups, instances and lookups — without opening VRCNext’s dialogs. |
| Routes & deep links | In-page HTTP routes, vrcn:// links, and their limits. |
| Logging | The logger, the Logs panel, the bridge’s log file. |
Plugins
| Plugin | What it does |
|---|---|
| Club Security | Per-club presets that report who joins your instance and whether they meet the club’s rules. |
| Bio Updater | Writes your bio, status, pronouns and links from templates, fitted by priority rather than cut. |
| VRCNext Patches | Small fixes VRCNext does not make: media-library folders, unattended sign-in. |
| The template plugin | Every capability, one per file — start a plugin from it. |
Reference
| Page | What it covers |
|---|---|
| Publishing & updates | Versioning, how updates reach users, apiVersion. |
| Signing plugins | The signing key, plugin.sig, and what the bridge checks. |
| Using TSX | JSX in plugins: vendor the renderer, and why VRCNext itself has no framework. |
| Security model | What plugins can do, and what the system does about it. |
| Limitations | What is genuinely impossible without patching VRCNext. |
| API reference | Every exported type, one page. |
Contributing
| Page | What it covers |
|---|---|
| Contributing | Working on these repositories: the gates, the rules that hold everywhere, signing, the local loop. |
Internals
| Page | What it covers |
|---|---|
| Bridge reference | The daemon’s protocol, services, install pipeline, build and security design. |
| Running the bridge | Autostart, flags, remote control, troubleshooting. |
| Plugin system internals | How the host boots and is built, its repository layout, development. |
| Design: the pre-bundled architecture | The original plan, kept for its reasoning. |
Repositories
| Repository | Purpose |
|---|---|
| vrcnext-plugin-system | The host, the typed @vrcnext/plugin-api contract and the installer. |
| vrcnext-example-plugin | The template repository: a working plugin using every capability, one per file. |
| vrcnext-bridge | The native companion daemon. Rust, loopback only, one WebSocket. |
| vrcnext-club-security-plugin, vrcnext-bio-updater-plugin, vrcnext-patches-plugin | The plugins above. |
| vrcnext-plugins.github.io | This site. |
A note on trust
Plugins run inside the VRCNext page with the full authority of the user’s VRChat session. There
is no sandbox. The permission model makes each capability declared and each
concrete use confirmed, and the source policy keeps plugins on the ctx.*
path — neither contains a plugin that is determined to misbehave. Every tree must also be
signed by its author, and a plugin stays pinned to the key it was installed with,
so a repository changing hands cannot quietly become an update. Installing a plugin is still
equivalent to running a program from that repository. See the security model.