> ## Documentation Index
> Fetch the complete documentation index at: https://dadd.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# useTrajectoryRecorder

> Record simulation trajectories

Record simulation trajectories (qpos, qvel, ctrl, sensordata) for playback, analysis, or export.

## Signature

```tsx theme={null}
useTrajectoryRecorder(options?: {
  fields?: ("qpos" | "qvel" | "ctrl" | "sensordata")[];
}): {
  start: () => void;
  stop: () => TrajectoryFrame[];
  recording: boolean;
  frameCount: number;
  frames: TrajectoryFrame[];
  downloadJSON: () => void;
  downloadCSV: () => void;
}
```

## Usage

```tsx theme={null}
import { useTrajectoryRecorder } from "mujoco-react";

function RecordButton() {
  const recorder = useTrajectoryRecorder({
    fields: ["qpos", "qvel", "ctrl"],
  });

  return (
    <div>
      {recorder.recording ? (
        <button onClick={() => {
          const frames = recorder.stop();
          console.log(`Recorded ${frames.length} frames`);
        }}>
          Stop ({recorder.frameCount} frames)
        </button>
      ) : (
        <button onClick={recorder.start}>Record</button>
      )}
      <button onClick={recorder.downloadJSON}>Export JSON</button>
      <button onClick={recorder.downloadCSV}>Export CSV</button>
    </div>
  );
}
```

## Options

| Field    | Type       | Default                                  | Description                       |
| -------- | ---------- | ---------------------------------------- | --------------------------------- |
| `fields` | `string[]` | `['qpos', 'qvel', 'ctrl', 'sensordata']` | Which fields to record each frame |

## Return Value

| Field          | Type                      | Description                              |
| -------------- | ------------------------- | ---------------------------------------- |
| `start`        | `() => void`              | Begin recording                          |
| `stop`         | `() => TrajectoryFrame[]` | Stop recording and return frames         |
| `recording`    | `boolean`                 | Whether currently recording              |
| `frameCount`   | `number`                  | Number of frames recorded so far         |
| `frames`       | `TrajectoryFrame[]`       | Recorded frames (grows during recording) |
| `downloadJSON` | `() => void`              | Download trajectory as JSON file         |
| `downloadCSV`  | `() => void`              | Download qpos as CSV file                |

## TrajectoryFrame

```tsx theme={null}
interface TrajectoryFrame {
  time: number;
  qpos: Float64Array;
  qvel?: Float64Array;
  ctrl?: Float64Array;
  sensordata?: Float64Array;
}
```

## Notes

* Recording happens in `useAfterPhysicsStep` — one frame per physics step
* Each frame is a snapshot (arrays are copied, not referenced)
* JSON export includes all recorded fields; CSV includes qpos only
* For playback, pass `recorder.frames` directly to [`useTrajectoryPlayer`](/hooks/use-trajectory-player) or [`<TrajectoryPlayer>`](/components/trajectory-player) — no format conversion needed
