Plugin System
vue-threejs includes a root-scoped plugin system that lets packages hook into the renderer lifecycle, provide values to the component tree, and register Three.js extensions — all without tight coupling to Canvas internals.
TIP
The plugin system is the recommended way to integrate ecosystem packages like @bluera/vue-threejs-drei, @bluera/vue-threejs-postprocessing, and @bluera/vue-threejs-rapier.
Defining a plugin
Use defineFiberPlugin to create a type-safe plugin definition:
import { defineFiberPlugin } from '@bluera/vue-threejs'
export const myPlugin = defineFiberPlugin({
name: 'my-plugin',
setup(ctx) {
// ctx exposes: appContext, canvas, store, extend, provide,
// onDispose, invalidate, getState
ctx.extend({ MyCustomObject })
ctx.provide(MY_KEY, { hello: 'world' })
ctx.onDispose(() => {
// cleanup when the Canvas unmounts
})
},
})Plugin context
The setup function receives a FiberPluginContext with:
| Property | Description |
|---|---|
appContext | The Vue app context (or null) |
canvas | The HTMLCanvasElement or OffscreenCanvas |
store | The root Zustand store |
extend | Register Three.js constructors into the catalogue |
provide | Inject a value into the plugin provider subtree |
onDispose | Register a cleanup callback (runs in reverse order) |
invalidate | Request re-render frames (for demand rendering) |
getState | Get a snapshot of the current root state |
Options
Plugins can accept typed options:
import { defineFiberPlugin, withPluginOptions } from '@bluera/vue-threejs'
export interface MyPluginOptions {
debug?: boolean
quality?: 'low' | 'medium' | 'high'
}
export const myPlugin = defineFiberPlugin<MyPluginOptions>({
name: 'my-plugin',
setup(ctx, options) {
if (options?.debug) console.log('debug mode')
ctx.provide(MY_DEFAULTS, options)
},
})
// Convenience factory
export function createMyPlugin(options?: MyPluginOptions) {
return withPluginOptions(myPlugin, options)
}Dependencies
Declare dependencies with requires for guaranteed initialization order:
export const effectsPlugin = defineFiberPlugin({
name: 'my-effects',
requires: ['@bluera/vue-threejs-postprocessing'],
setup(ctx) {
// postprocessing plugin is guaranteed to have run first
},
})Missing or circular dependencies throw at runtime with clear error messages.
Registering plugins
Canvas-level
Pass plugins directly to a Canvas:
<script setup>
import { Canvas } from '@bluera/vue-threejs'
import { createDreiPlugin } from '@bluera/vue-threejs-drei'
import { createPostprocessingPlugin } from '@bluera/vue-threejs-postprocessing'
const plugins = [createDreiPlugin({ dracoPath: '/draco/' }), createPostprocessingPlugin({ multisampling: 4 })]
</script>
<template>
<Canvas :plugins="plugins">
<!-- scene content -->
</Canvas>
</template>App-level
Register plugins once for every Canvas in the app:
import { createApp } from 'vue'
import { registerFiberPlugin } from '@bluera/vue-threejs'
import { dreiFiberPlugin } from '@bluera/vue-threejs-drei'
const app = createApp(App)
registerFiberPlugin(app, dreiFiberPlugin)
app.mount('#app')App-level and Canvas-level plugins are merged automatically. Canvas plugins override app plugins with the same name (last-write-wins).
Plugin entry forms
Plugins can be passed in three forms:
// 1. Bare definition (no options)
[myPlugin]
// 2. Tuple
[myPlugin, { debug: true }]
// 3. Object (preferred for stable identity)
{ plugin: myPlugin, options: { debug: true }, key: 'my-unique-key' }Inheritance
By default, Canvas inherits app-level plugins. Disable with:
<Canvas :inherit-plugins="false" :plugins="[myPlugin]">
<!-- only myPlugin, no app-level plugins -->
</Canvas>Lifecycle
- Normalize — all entry forms are resolved to a uniform shape
- Deduplicate — plugins with the same name are deduped (last wins)
- Sort — topological sort based on
requiresdependencies - Setup —
plugin.setup()called in dependency order - Dispose — cleanup functions run in reverse order on unmount
Official plugins
@bluera/vue-threejs-drei— controls, loaders, staging, helpers@bluera/vue-threejs-postprocessing— GPU postprocessing effects@bluera/vue-threejs-rapier— physics simulation