Vite plugin
Install the devtools, the bridge and the devframe Vite adapter:
npm install -D @vkma.dev/devtools @vkma.dev/bridge devframe @devframes/viteAdd the plugin to vite.config.ts:
import { vkmaDevtools } from "@vkma.dev/devtools";
export default { plugins: [vkmaDevtools()],};Run vite dev — next to the app URL the terminal prints vkma devtools → http://localhost:5173/__vkma/. What lives inside the panel is covered in its tour.
What the plugin does
Section titled “What the plugin does”- The
/__vkma/panel. An SPA with RPC/WebSocket on Vite’s own port, like/__unocssfor UnoCSS. No extra server is started./__vkmawithout a trailing slash 308-redirects to/__vkma/. - The bridge alias. Imports of
@vkontakte/vk-bridge— from dependencies too — resolve to@vkma.dev/bridgewith a built-in tap, so the panel sees all of the app’s traffic without touching the app’s code. - The FAB. A floating button on the app page opens the same panel as an overlay.
Options
Section titled “Options”vkmaDevtools({ base: "/__vkma/", alias: true, fabPosition: "bottom-left", mcp: false, allowedOrigins: false, hub: false,});| Option | Type | Default | What it does |
|---|---|---|---|
base |
string |
"/__vkma/" |
Base for the panel, the RPC bridge and the MCP route |
alias |
boolean |
true |
Alias @vkontakte/vk-bridge → @vkma.dev/bridge in the dev build |
fabPosition |
"bottom-left" | "bottom" | "bottom-right" |
"bottom-left" |
Initial FAB placement; a placement picked in the panel is remembered per origin and wins |
mcp |
boolean or an McpRouteOptions object |
false |
MCP tools at <base>__mcp for coding agents |
allowedOrigins |
false or a list of origins |
false |
WebSocket Origin check; false means any origin (the OTP gate stays the trust boundary) |
hub |
boolean |
false |
Mount the panel as a Vite DevTools dock instead of a standalone page |
bridge |
object | — | Extra RPC-bridge options, forwarded verbatim to devframeViteBridge |
The plugin runs in dev only (apply: "serve") — production builds are untouched.
Importing @vkma.dev/bridge directly
Section titled “Importing @vkma.dev/bridge directly”If the app imports @vkma.dev/bridge itself, the alias is redundant — the package publishes its own tap and the collector finds it. Turn the interception off:
vkmaDevtools({ alias: false });The alias exists for exactly one job: routing someone else’s @vkontakte/vk-bridge imports through the tap as well.
Phones and tunnels
Section titled “Phones and tunnels”Run vite --host and open the app from a phone on your LAN — it becomes another panel client. The first browser connection goes through an OTP gate: a one-time code is printed in the dev server terminal (with a one-click link next to it); trusted browsers are remembered. The WebSocket Origin check is open by default — the OTP stays the trust boundary; pass allowedOrigins: ["http://192.168.1.5:5173"] to close it as well.
Vite DevTools dock
Section titled “Vite DevTools dock”With @vitejs/devtools installed, mount the panel as one of its docks instead of a standalone page:
import { DevTools } from "@vitejs/devtools";import { vkmaDevtools } from "@vkma.dev/devtools";
export default { plugins: [DevTools(), vkmaDevtools({ hub: true })],};The hub then owns the panel and the RPC; the plugin keeps the bridge interception and the FAB. MCP aggregates into the hub’s endpoint /__devtools/__mcp and the mcp option is ignored. Without hub: true nothing changes — with or without Vite DevTools present.