This is a documentation page for the r3f extension that makes it easier to use Theatre.js with React Three Fiber. Want to learn how to set up Theater.js with React Three Fiber? Head over to the Getting Started with React Three Fiber page


The editable object can be used either as a React component to create editable versions of r3f elements, or as a function to create editable versions of React components that have an API that matches that of a supported React Three Fiber element.

editable – as a React component

You can create editable versions of React Three Fiber elements using properties on the editable object.

<editable.pointLight theatreKey="Key light" />

These elements behave the same as the originals, but also show up in the Studio.

While they take the same props as their r3f counterparts, there are a couple of Theatre.js-specific props.


The element's object's name in Theatre.js. All editable elements need to have a theatreKey prop so that they can be connected to a backing-object.

<editable.group theatreKey="My group" />


The visible prop is the same as for all r3f elements, however, while regular r3f elements can only take true or false, editable elements can take a third, 'editor' option that signals to Theatre.js that we only want the object to be visible in the snapshot editor. This is helpful for helper objects that we don't want to be part of the final scene.

<editable.mesh theatreKey="Marker" visible="editor">
<boxBufferGeometry />
<meshBasicMaterial color="yellow" />


Allows you to specify additional Theatre.js props under the backing-object of the element. These props won't have an immediate effect on the element, but you can observe them by subscribing to the element's backing-object directly through objRef.

theatreKey="My group"
myCustomProp: types.number(0, {
nudgeMultiplier: 0.1,


Exposes the element's backing-object directly.

const MyComponent: React.FC = () => {
const objRef = useRef<ISheetObject>()
return <editable.group theatreKey="My group" objRef={objRef} />


This prop is only used when using editable.primitive, since primitive elements can represent any THREE.js object. The editableType prop tells Theatre.js what THREE.js object type to assume in this case.

<editable.primitive object={myMesh} theatreKey="My Mesh" editableType="mesh" />

editable – as a function

You can also use editable as a function to create editable versions of react components that have an API that matches that of a supported React Three Fiber element.

import { editable } from '@theatre/r3f'
import { PerspectiveCamera } from '@react-three/drei'
const EditableCamera = editable(PerspectiveCamera, 'perspectiveCamera')


All editable elements are backed by a Theatre.js sheet object. The r3f extension needs to know what sheet to attach these objects to. The way it does this is through the SheetProvider React component. SheetPoviders can be arbitrarily placed and nested, there are only two rules:

  1. All editable elements need to be a descendant of a SheetProvider.
  2. All editable elements need to have a unique theatreKey prop under their SheetProvider. theatreKeys across sheets don't need to be unique.

<SheetProvider getSheet={getProject('Playground - R3F').sheet('R3F-Canvas')}>
<ambientLight intensity={0.5} />
<editable.spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} theatreKey="Spotlight" />
<editable.pointLight theatreKey="PointLight" />
<editable.mesh theatreKey="Box">
<boxBufferGeometry />
<meshStandardMaterial color="orange" />


The sheet that the SheetProvider should provide.


Hook to access the sheet of the nearest SheetProvider.


Utility to refresh the snapshot in the snapshot editor from code. Useful for example to refresh the snapshot editor when some assets have loaded that otherwise would not be visible.

import { refreshSnapshot } from '@theatre/r3f'


React component that refreshes the snapshot editor on mount. Useful when you use Suspense to wait for assets to load, and you want to refresh when the suspended components render.

<Suspense fallback={Fallback}>
<RefreshSnapshot />
<MyModel />


JS object used to register the extension with the Studio.

Note, extension is not exported from @theatre/r3f! It is instead exported from @theatre/r3f/dist/extension in order to aid in excluding it and Studio from production code.

import { extension } from '@theatre/r3f/dist/extension'
import studio from '@theatre/studio'

Was this article helpful to you?

Last edited on September 29, 2022.
Edit this page

Theatre.js is a design tool in the making. We aim to blur the line between designer/developer, author/consumer, and artist/scientist.
© 2022 Theatre.js Oy – Helsinki.