threlte logo


Plugins are one of Threlte’s superpowers. Plugins allow you to globally extend Threlte’s <T> component functionality. This means you can not only add arbitrary props and event handlers to your <T> components but also override the default behavior of the <T> component entirely.

Plugins add code to every <T> component instance. That code acts as if it were part of the <T> component itself. You have full access to props, event listeners and the component instance itself. For an advanced example of what a plugin can do, see the interactivity plugin of @threlte/extras.


The function injectPlugin adds a plugin to all descendant <T> components of the component that invokes it. This means that you can add plugins to a specific part of your scene graph without affecting the rest of the scene graph.

import { injectPlugin } from '@threlte/core'

injectPlugin('plugin-name', ({ ref, props }) => {
  // We are *inside* a `<T>` component instance

  // Do something with the ref and props
  // e.g. return early if the plugin is not applicable

  return {
    // These props are reserved for this plugin, the
    // `<T>` component instance will not act on them.
    pluginProps: ['plugin-prop-a', 'plugin-prop-b'],

    // this function is called whenever the `ref` inside the `<T>`
    // component changes. You may return a cleanup function that is
    // called when the ref changes again or the component unmounts.
    onRefChange: (ref) => {
      // Do something with the ref
      return () => {
        // Cleanup

    // This function is called whenever the $$props of the `<T>` component
    // change. These include props like "dispose", "args" and "makeDefault"
    // that are part of the component itself rather than the props that are
    // passed to the Three.js object.
    onPropsChange: (props) => {
      // Do something with the props

    // This function is called whenever the $$restProps of the `<T>` component
    // change. These are the props that are passed to the Three.js object.
    onRestPropsChange: (restProps) => {
      // Do something with the restProps

You may also override a plugin namespace further down the tree by calling injectPlugin again with the same plugin name.

injectPlugin is relying on a context provided by your root <Canvas> component and can therefore only be used inside a <Canvas> component.


The function createPlugin creates a NamedPlugin but does not add it to the global plugin list and therefore does not make it available to all <T> components. This is useful if you want to create a plugin at some place and inject it at another.

import { createPlugin } from '@threlte/core'

export const plugin = createPlugin('plugin-name', ({ ref, props }) => {
  // Plugin Code
<script lang="ts">
  import { injectPlugin } from '@threlte/core'
  import { plugin } from './plugin'