"use client"; import type React from "react"; import { Book, Code2, Terminal, Copy, Check } from "lucide-react"; import { Button } from "@/components/ui/button"; import { useState } from "react"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; import { oneDark } from "react-syntax-highlighter/dist/esm/styles/prism"; const CodeBlock = ({ children, language = "typescript", }: { children: React.ReactNode; language?: string; }) => { const [copied, setCopied] = useState(false); const copyToClipboard = async (text: string) => { try { await navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch (err) { console.error("Failed to copy:", err); } }; const codeText = typeof children === "string" ? children : children?.toString() || ""; return (
{codeText}
); }; export function DocsSection() { return (

Docs

Complete API reference for @lerobot/web

{/* Browser Requirements */}

Browser Requirements

Chromium 89+ with WebSerial and WebUSB API support
HTTPS or localhost
User gesture required for initial port selection
{/* Getting Started */}

Getting Started

Complete workflow from discovery to teleoperation.

{`import { findPort, releaseMotors, calibrate, teleoperate } from "@lerobot/web"; // 1. find and connect to hardware like a robot arm const findProcess = await findPort(); const robots = await findProcess.result; const robot = robots[0]; // 2. release the motors and put them into the homing position await releaseMotors(robot); // 3. calibrate the motors by moving each motor through its full range of motion const calibrationProcess = await calibrate({ robot, onProgress: (message) => console.log(message), onLiveUpdate: (data) => console.log("Live positions:", data), }); // when done, stop calibration and get the min/max ranges for each motor calibrationProcess.stop(); const calibrationData = await calibrationProcess.result; // 4. start controlling the robot arm with your keyboard const teleop = await teleoperate({ robot, calibrationData, teleop: { type: "keyboard" }, }); teleop.start(); // 5. stop control (run this when you're done) teleop.stop();`}
{/* API Reference */}

API Reference

{/* findPort */}

findPort(config?)

Discovers and connects to robotics hardware using WebSerial API.

{`// Interactive Mode (Default) - Shows port dialog const findProcess = await findPort(); const robots = await findProcess.result; // RobotConnection[] // Auto-Connect Mode - Reconnects to known robots const findProcess = await findPort({ robotConfigs: [ { robotType: "so100_follower", robotId: "left_arm", serialNumber: "USB123" } ], onMessage: (msg) => console.log(msg), });`}
Options
  • robotConfigs?: RobotConfig[] - Auto-connect to these known robots
  • onMessage?: (message: string) => void - Progress messages callback
Returns:{" "} FindPortProcess
  • result: Promise<RobotConnection[]> - Array of robot connections
  • stop(): void - Cancel discovery process
{/* calibrate */}

calibrate(config)

Calibrates motor homing offsets and records range of motion.

{`const calibrationProcess = await calibrate({ robot, onProgress: (message) => { console.log(message); // "⚙️ Setting motor homing offsets" }, onLiveUpdate: (data) => { // Real-time motor positions during range recording Object.entries(data).forEach(([motor, info]) => { console.log(\`\${motor}: \${info.current} (range: \${info.range})\`); }); }, }); // Move robot through full range of motion... calibrationProcess.stop(); // Stop range recording const calibrationData = await calibrationProcess.result;`}
Options
  • robot: RobotConnection - Connected robot from findPort()
  • onProgress?: (message: string) => void - Progress messages callback
  • •{" "} onLiveUpdate?: (data: LiveCalibrationData) => void {" "} - Real-time position updates
Returns:{" "} CalibrationProcess
  • result: Promise<WebCalibrationResults>{" "} - Python-compatible format
  • stop(): void - Stop calibration process
{/* teleoperate */}

teleoperate(config)

Enables real-time robot control with extensible input devices.

{`// Keyboard Teleoperation const keyboardTeleop = await teleoperate({ robot, calibrationData: savedCalibrationData, teleop: { type: "keyboard" }, onStateUpdate: (state) => { console.log(\`Active: \${state.isActive}\`); console.log(\`Motors:\`, state.motorConfigs); }, }); // Direct Teleoperation const directTeleop = await teleoperate({ robot, calibrationData: savedCalibrationData, teleop: { type: "direct" }, });`}
Options
  • robot: RobotConnection - Connected robot from findPort()
  • teleop: TeleoperatorConfig - Teleoperator configuration:
    • {`{ type: "keyboard" }`} - Keyboard control
    • {`{ type: "direct" }`} - Direct programmatic control
  • •{" "} calibrationData?: {`{ [motorName: string]: any }`} {" "} - Calibration data from calibrate()
  • •{" "} onStateUpdate?: (state: TeleoperationState) => void {" "} - State change callback
Returns:{" "} TeleoperationProcess
  • start(): void - Begin teleoperation
  • stop(): void - Stop teleoperation and clear states
  • getState(): TeleoperationState - Current state and motor positions
  • teleoperator: BaseWebTeleoperator - Access teleoperator-specific methods
  • disconnect(): Promise<void> - Stop and disconnect
{/* releaseMotors */}

releaseMotors(robot, motorIds?)

Releases motor torque so robot can be moved freely by hand.

{`// Release all motors for calibration await releaseMotors(robot); // Release specific motors only await releaseMotors(robot, [1, 2, 3]);`}
Options
  • robot: RobotConnection - Connected robot
  • motorIds?: number[] - Specific motor IDs (default: all motors for robot type)
); }