Numerous Pulls Merged

    TypeScript icon, indicating that this package has built-in type declarations

    4.0.0-alpha2 • Public • Published


    Version Downloads Discord Shield

    React components and hooks for creating VR/AR applications with @react-three/fiber

    npm install @react-three/xr


    These demos are real, you can click them! They contain the full code, too.

    Getting started

    Add VRCanvas or ARCanvas component (or replace your existing react-three-fiber Canvas component)

    import { VRCanvas } from '@react-three/xr'
    function App() {
      return (
          {/* All your regular react-three-fiber elements go here */}

    Adding controllers to the scene

    To get started with default controller models add DefaultXRControllers component. It will fetch appropriate input profile models. You can learn more here.

    import { VRCanvas, DefaultXRControllers } from '@react-three/xr'
      <DefaultXRControllers />

    You can access controllers' state (position, orientation, etc.) by using useXR() hook

    const { controllers } = useXR()


    To interact with objects using controllers you can use <Interactive> component or useInteraction hook. They allow adding handlers to your objects. All interactions are use rays that are shot from the controllers.


    Use this component to wrap your objects and pass handlers as props. Supports select, hover, blur and squeeze events.

    const [isHovered, setIsHovered] = useState(false)
    return (
      <Interactive onSelect={() => console.log('clicked!')} onHover={() => setIsHovered(true)} onBlur={() => setIsHovered(false)}>
        <Box />


    Wrap any object with a RayGrab component to make it grabbable

      <Box />


    Attach handler to an existing object in a scene

    const ref = useResource()
    useInteraction(ref, 'onSelect', () => console.log('selected!'))
    return <Box ref={ref} />


    To handle controller events that are not bound to any object in the scene you can use useXREvent() hook.

    Every controller emits following events: select, selectstart, selectend, squeeze, squeezestart, squeezeend.

    useXREvent('squeeze', (e) => console.log('squeeze event has been triggered'))

    it supports optional third parameter with options

    useXREvent('squeeze', () => console.log('Left controller squeeze'), { handedness: 'left' })

    VRCanvas, ARCanvas componentss

    Extended react-three-fiber Canvas that includes:

    • Button to start VR session
    • Color management
    • VR Mode
    • react-xr context

    For VR apps use VRCanvas and for AR apps use ARCanvas

    import { VRCanvas } from '@react-three/xr'
      {/* All your regular react-three-fiber elements go here */}


    Hook that can only be used by components inside XRCanvas component.

    const { controllers, player, isPresenting } = useXR()

    Controllers is an array of XRController objects

    interface XRController {
      grip: Group
      controller: Group
      inputSource: XRInputSource
      // ...
      // more in XRController.ts

    grip and controller are ThreeJS groups that have the position and orientation of xr controllers. grip has an orientation that should be used to render virtual objects such that they appear to be held in the user’s hand and controller has an orientation of the preferred pointing ray.

    inputSource is the WebXR input source (MDN). Note that it will not be available before controller is connected.


    Use this hook to get an instance of the controller

    const leftController = useController('left')



    Use this hook to perform a hit test for an AR environment

    To enable hit testing in your AR app add sessionInit prop to ARCanvas like this

    <ARCanvas sessionInit={{ requiredFeatures: ['hit-test'] }}>

    And then in your component handle hit with useHitTest hook

    useHitTest((hitMatrix, hit) => {
      // use hitMatrix to position any object on the real life surface


    Add hands model for hand-tracking. Works out of the box on Oculus Browser v13, and can be enabled on versions as low as v10.2 with #webxr-hands experimental flag enabled.

      <Hands />

    Custom hands model

    While a default model is provided, you might want to use a different model that fit your design. It can work with any glTF model as long as they're ready for WebXR handtracking. If you don't specify a model for one hand it'll use the default one.

    <Hands modelLeft={'/model_left.gltf'} modelRight={'/model_right.glb'} />


    player group contains camera and controllers that you can use to move player around

    const { player } = useXR()
    useEffect(() => {
      player.position.x += 5
    }, [])

    Version 4 migration guide

    @react-three/xr@4 is updated to react@18 and @react-three/fiber@8

    Explore Examples

    You can explore additional examples locally. Make sure you have nodejs and yarn installed.

    Clone repository with:

    git clone
    cd react-xr

    Install dependencies with:


    Once it's done start up a local server with:

    yarn dev


    npm i @saitonakamura/react-three-xr

    DownloadsWeekly Downloads






    Unpacked Size

    114 kB

    Total Files


    Last publish


    • saitonakamura