Plugin dependencies
Every plugin mounts independently inside <Visualizer />, and none requires another plugin to function. A few, though, rely on optional npm packages, a live machine connection, or coordinate with a sibling plugin at runtime. This page audits those relationships so you know what to install and mount together.
External packages
Section titled “External packages”Most plugins need nothing beyond @viamrobotics/visualization. Several use optional peer dependencies — install them only when you use the plugin:
| Plugin | Install |
|---|---|
<SelectionTool /> | earcut |
<DrawService /> | @connectrpc/connect @connectrpc/connect-web |
<Debug /> | @tanstack/svelte-query-devtools |
<MoveFrame /> | @dimforge/rapier3d-compat @threlte/rapier |
<Settings /> | @zag-js/tabs |
<WorldTree /> | @zag-js/tree-view svelte-virtuallists |
<XR /> | @threlte/xr |
Two more build on packages that ship as required peers of @viamrobotics/visualization — already installed with it, and listed here only for completeness:
| Plugin | Required peers |
|---|---|
<ControlWidgets /> | @viamrobotics/test-widgets, @viamrobotics/svelte-sdk |
<XR /> | @viamrobotics/svelte-sdk |
Plugin-to-plugin
Section titled “Plugin-to-plugin”No plugin imports another as a hard requirement, but several pairs coordinate at runtime. Each is soft: the dependent plugin still works alone, just with reduced behavior.
| Plugin | Coordinates with | What happens |
|---|---|---|
<ControlWidgets /> | <XR /> | Registry widget panels are hidden while an immersive XR session is active. |
<DrawService /> | <Logs /> | Connection status and errors are written to the Logs panel. Without Logs, they’re dropped silently. |
| mode plugins | each other | Buttons portal into the mode toggle in mount order, which is also fallback priority. Mount Monitor first. |
<FramePov /> | <XR /> | POV panels hide while an immersive session owns the canvas. |
any SettingsPortal user | <Settings /> | The contributed tab is registered either way, but only renders when Settings is mounted. |
The <ControlWidgets /> ──► <XR /> link only observes the session state XR publishes to useEnvironment().current.isImmersive, not the other plugin’s internals — which is what lets @threlte/xr stay an optional peer. Which cameras appear in a headset is chosen independently in the <XR /> plugin’s own AR settings panel.
Plugins
Section titled “Plugins”Plugins are the visualizer’s own chrome, split out so an embedded viewer doesn’t inherit UI it has no use for: <Monitor />, <WorldTree />, <Settings />, <BuildFrames />, <FileDrop />, and <FramePov />. Mount all six — Monitor first, so it is the default mode — for the full standalone app; mount none for a bare scene with camera controls.
One of them reaches beyond the visualizer element: <FileDrop /> listens for drags on window, so it swallows drag-and-drop for the whole page. Keyboard shortcuts are dispatched by core but exist only when the feature contributing them is mounted, and inputBindingsEnabled={false} disables keyboard input wholesale.
Runtime requirements
Section titled “Runtime requirements”Some plugins need more than a mounted <Visualizer />:
| Plugin | Also needs |
|---|---|
<ControlWidgets />, <XR />, <FramePov /> | a live machine connection (resources resolved per part) |
<BuildFrames /> | a partID and edit permissions on that part |
<XR /> | a WebXR-capable device to enter a session |
<Focus /> | an active selection — click an entity first |
<DrawService /> | a running draw server (see its page) |
<TopDownLock /> | orbit-style camera controls (the default); no effect under trackball controls |
<FramePov /> | a POV panel opened from a frame’s details card |