Skip to main content

useThree gives you the three.js context from inside a <Canvas> — the renderer, scene, camera, raycaster, and more.

Signature

// The full context object
useThree(): Context
// A reactive accessor for one derived value
useThree<T>(selector: (context: Context) => T): Accessor<T>

Call it with no arguments for the whole context. Pass a selector to derive a single value reactively:

const camera = useThree(context => context.camera)
// camera() is an Accessor<Camera>

Returns

PropertyTypeDescription
boundsMeasureReactive canvas bounds measurement.
viewportViewportViewport measurements — width, height, top, left, plus factor, distance, and aspect.
cameraCameraKindThe current camera (PerspectiveCamera | OrthographicCamera).
setCamera(camera: CameraKind) => () => voidPush a camera onto the stack, making it active. Returns a cleanup that pops it. Accepts only a PerspectiveCamera or OrthographicCamera.
canvasHTMLCanvasElementThe canvas DOM element.
clockClockThe three.js clock, for timing.
dprnumberDevice pixel ratio of the active renderer. Falls back to 1 for renderers without getPixelRatio (e.g. CSS3DRenderer, SVGRenderer).
glMeta<ResolvedRenderer>The active renderer, wrapped with meta so you can read solid-three metadata via getMeta(three.gl). Narrow it project-wide with Register augmentation.
raycasterRaycaster | EventRaycasterThe current raycaster used for pointer events.
setRaycaster(raycaster: Raycaster) => () => voidPush a raycaster onto the stack. Returns a cleanup that pops it.
render(timestamp: number, frame?: XRFrame) => voidRender one frame now. Pass a timestamp (e.g. performance.now()); the optional XRFrame is forwarded to useFrame callbacks. This is the per-frame primitive you hand to gl.setAnimationLoop when driving a WebXR session.
requestRender() => voidRequest a render on the next frame. Skipped while an XR session is presenting (the session owns the loop).
sceneMeta<Scene>The root scene, wrapped with meta.
propsCanvasPropsThe props the host <Canvas> was rendered with.

Behavior

The camera and raycaster are each managed as a stack. The camera and raycaster from <Canvas> props sit at the bottom; whatever is on top is the active one that three.camera / three.raycaster return.

setCamera and setRaycaster push a new one onto the stack, making it active, and return a cleanup that pops it back off — restoring the previous one. Pair the cleanup with onCleanup so the previous camera or raycaster comes back when your component unmounts.

WebXR

solid-three does not manage XR sessions for you — entering and exiting a session is the consumer's job. For almost all cases, reach for createXR, which handles the session-ordering rules for you.

If you need to drive the renderer directly instead, the rule to remember is: install the render callback before setSession runs.

const { gl, render } = useThree()
// enter XR
gl.setAnimationLoop(render) // must be set before setSession
gl.xr.enabled = true
const session = await navigator.xr.requestSession("immersive-vr")
await gl.xr.setSession(session)
// exit XR
gl.setAnimationLoop(null)
gl.xr.enabled = false

While a session is presenting, the renderer's own loop (driven by the headset) owns rendering, so solid-three's window loop steps aside automatically. The same code works for both WebGLRenderer and WebGPURenderer. For XR with WebGPURenderer on three ≤ r184, construct it with { forceWebGL: true }.

Examples

Switching to an orthographic camera while a signal is set, and restoring the previous one on cleanup:

const three = useThree()
const [useOrtho, setUseOrtho] = createSignal(false)
createEffect(() => {
if (useOrtho()) {
const orthoCamera = new OrthographicCamera(-5, 5, 5, -5, 0.1, 1000)
orthoCamera.position.set(0, 0, 5)
const restore = three.setCamera(orthoCamera)
onCleanup(restore)
}
})

See also

  • <Canvas/> — sets the default camera, raycaster, and scene this hook reads.
  • Raycasters — the raycaster types setRaycaster accepts.
  • Metadata — reading solid-three metadata off gl and scene.

Last updated: 6/8/26, 11:20 AM

solid threeA SolidJS renderer for three.js — learn by reading.
Community
github