Skip to main content
A thin wrapper around React Three Fiber’s <Canvas> that sets up the physics simulation. Accepts all standard R3F Canvas props plus MuJoCo-specific configuration.

Usage

import { useRef } from "react";
import { MujocoProvider, MujocoCanvas } from "mujoco-react";
import type { MujocoSimAPI } from "mujoco-react";
import { OrbitControls } from "@react-three/drei";

function App() {
  const apiRef = useRef<MujocoSimAPI>(null);

  return (
    <MujocoProvider>
      <MujocoCanvas
        ref={apiRef}
        config={{
          src: "https://raw.githubusercontent.com/google-deepmind/mujoco_menagerie/main/franka_emika_panda/",
          sceneFile: "scene.xml",
        }}
        camera={{ position: [2, -1.5, 2.5], up: [0, 0, 1], fov: 45 }}
        shadows
        paused={false}
        speed={1.0}
        style={{ width: "100%", height: "100vh" }}
      >
        <OrbitControls makeDefault />
        <ambientLight intensity={0.7} />
      </MujocoCanvas>
    </MujocoProvider>
  );
}

Props

MuJoCo Props

config
SceneConfig
required
Scene configuration — robot ID, model file, joints, etc. See Loading Models.
onReady
(api: MujocoSimAPI) => void
Fires when the model is loaded and simulation is ready. Receives the full API object.
onError
(error: Error) => void
Called if model loading or simulation fails.
onStep
(time: number) => void
Called after each physics step with the current simulation time.
onSelection
(bodyId: number, name: string) => void
Fired when a body is double-clicked in the scene.

Physics Props

paused
boolean
default:"false"
Pause/resume the simulation declaratively.
speed
number
default:"1.0"
Simulation speed multiplier. 0.5 = half speed, 2.0 = double speed.
gravity
[number, number, number]
Override gravity vector (m/s^2). Default: model’s gravity.
timestep
number
Override simulation timestep (seconds). Default: model’s timestep.
substeps
number
Number of physics substeps per frame for improved stability.

R3F Canvas Props

All standard @react-three/fiber Canvas props are passed through:
<MujocoCanvas
  camera={{ position: [2, 2, 2], fov: 45, up: [0, 0, 1] }}
  shadows
  dpr={[1, 2]}
  gl={{ antialias: true }}
  style={{ width: "100%", height: "100vh" }}
  className="my-canvas"
>

Ref

MujocoCanvas forwards its ref as a MujocoSimAPI handle — the same object passed to onReady:
const apiRef = useRef<MujocoSimAPI>(null);

<MujocoCanvas ref={apiRef} config={config}>
  {/* ... */}
</MujocoCanvas>

// Later: apiRef.current?.reset()

Notes

  • Must be a child of <MujocoProvider>
  • Children can use all mujoco-react hooks (useMujoco, useBeforePhysicsStep, etc.)
  • The config prop is read on mount and when api.loadScene() is called — changing it after mount has no effect