Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"JavaScript SDK & Web Apps","local":"javascript-sdk--web-apps","sections":[{"title":"Why Web Apps?","local":"why-web-apps","sections":[],"depth":2},{"title":"Architecture","local":"architecture","sections":[],"depth":2},{"title":"Quick Start","local":"quick-start","sections":[{"title":"1. Create a Hugging Face Space","local":"1-create-a-hugging-face-space","sections":[],"depth":3},{"title":"2. Add the SDK","local":"2-add-the-sdk","sections":[],"depth":3},{"title":"3. Connect to your robot","local":"3-connect-to-your-robot","sections":[],"depth":3},{"title":"4. Control the robot","local":"4-control-the-robot","sections":[],"depth":3},{"title":"5. Receive robot state","local":"5-receive-robot-state","sections":[],"depth":3},{"title":"6. Audio","local":"6-audio","sections":[],"depth":3},{"title":"7. Cleanup","local":"7-cleanup","sections":[],"depth":3}],"depth":2},{"title":"API Reference","local":"api-reference","sections":[{"title":"Constructor","local":"constructor","sections":[],"depth":3},{"title":"State Machine","local":"state-machine","sections":[],"depth":3},{"title":"Properties (read-only)","local":"properties-read-only","sections":[],"depth":3},{"title":"Methods","local":"methods","sections":[],"depth":3},{"title":"Events","local":"events","sections":[],"depth":3},{"title":"Math Utilities","local":"math-utilities","sections":[],"depth":3}],"depth":2},{"title":"Security","local":"security","sections":[],"depth":2},{"title":"Prerequisites","local":"prerequisites","sections":[],"depth":2},{"title":"Example","local":"example","sections":[],"depth":2}],"depth":1}"> | |
| <link href="/docs/reachy_mini/pr_970/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/entry/start.af5bca3c.js"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/chunks/scheduler.f05771bc.js"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/chunks/singletons.65ce4e8f.js"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/chunks/index.2528d289.js"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/chunks/paths.9fed6057.js"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/entry/app.7a7af01f.js"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/chunks/preload-helper.3945ace7.js"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/chunks/index.b379be46.js"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/nodes/0.4e8b4826.js"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/chunks/each.e59479a4.js"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/nodes/14.7ad07aa9.js"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/chunks/MermaidChart.svelte_svelte_type_style_lang.87a99dde.js"> | |
| <link rel="modulepreload" href="/docs/reachy_mini/pr_970/en/_app/immutable/chunks/CodeBlock.e4b2c5ba.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{"title":"JavaScript SDK & Web Apps","local":"javascript-sdk--web-apps","sections":[{"title":"Why Web Apps?","local":"why-web-apps","sections":[],"depth":2},{"title":"Architecture","local":"architecture","sections":[],"depth":2},{"title":"Quick Start","local":"quick-start","sections":[{"title":"1. Create a Hugging Face Space","local":"1-create-a-hugging-face-space","sections":[],"depth":3},{"title":"2. Add the SDK","local":"2-add-the-sdk","sections":[],"depth":3},{"title":"3. Connect to your robot","local":"3-connect-to-your-robot","sections":[],"depth":3},{"title":"4. Control the robot","local":"4-control-the-robot","sections":[],"depth":3},{"title":"5. Receive robot state","local":"5-receive-robot-state","sections":[],"depth":3},{"title":"6. Audio","local":"6-audio","sections":[],"depth":3},{"title":"7. Cleanup","local":"7-cleanup","sections":[],"depth":3}],"depth":2},{"title":"API Reference","local":"api-reference","sections":[{"title":"Constructor","local":"constructor","sections":[],"depth":3},{"title":"State Machine","local":"state-machine","sections":[],"depth":3},{"title":"Properties (read-only)","local":"properties-read-only","sections":[],"depth":3},{"title":"Methods","local":"methods","sections":[],"depth":3},{"title":"Events","local":"events","sections":[],"depth":3},{"title":"Math Utilities","local":"math-utilities","sections":[],"depth":3}],"depth":2},{"title":"Security","local":"security","sections":[],"depth":2},{"title":"Prerequisites","local":"prerequisites","sections":[],"depth":2},{"title":"Example","local":"example","sections":[],"depth":2}],"depth":1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"><div class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg></span> <span>Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg></button></div> </div> <h1 class="relative group"><a id="javascript-sdk--web-apps" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#javascript-sdk--web-apps"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>JavaScript SDK & Web Apps</span></h1> <p data-svelte-h="svelte-1q6nry0">Reachy Mini supports <strong>full JavaScript web apps</strong> that run entirely in the browser. No install, no server, no Python — just open a URL and control your robot from any device, including your phone.</p> <h2 class="relative group"><a id="why-web-apps" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#why-web-apps"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Why Web Apps?</span></h2> <p data-svelte-h="svelte-t2qw2z">The Python SDK is powerful but requires installation, GStreamer dependencies, and a capable machine. Web apps take a different approach:</p> <ul data-svelte-h="svelte-y8hb19"><li><strong>Zero install</strong> — open a link, you’re in. Save disk space and setup time.</li> <li><strong>Cross-platform</strong> — works on any device with a browser: laptop, tablet, phone.</li> <li><strong>Run from anywhere</strong> — control your robot from the other side of the world.</li> <li><strong>Leverage device hardware</strong> — use your phone’s microphone, speakers, and touchscreen.</li> <li><strong>Instant sharing</strong> — send someone a link, they can use the app immediately.</li></ul> <p data-svelte-h="svelte-75sclh">Web apps are deployed as <strong>static Hugging Face Spaces</strong> (<code>sdk: static</code>). There is no server-side code — the browser connects directly to the robot over WebRTC via a central signaling server.</p> <blockquote data-svelte-h="svelte-12dz101"><p>Python apps are not going away. Web apps are a complementary option, especially suited for lightweight control, remote access, and quick demos.</p></blockquote> <h2 class="relative group"><a id="architecture" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#architecture"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Architecture</span></h2> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->┌─────────────────────────────────┐ | |
| │ Browser │ | |
| │ (your app + reachy-mini<span class="hljs-selector-class">.js</span>) │ | |
| └───────┬────────────┬────────────┘ | |
| │ SSE/HTTP │ WebRTC (peer-<span class="hljs-selector-tag">to</span>-peer) | |
| │ signaling │ <span class="hljs-selector-tag">video</span> + <span class="hljs-selector-tag">audio</span> + data | |
| ┌───────▼──────┐ │ | |
| │ Signaling │ │ | |
| │ Server │ │ | |
| │ (HF Space) │ │ | |
| └───────┬──────┘ │ | |
| │ │ | |
| ┌───────▼────────────▼────────────┐ | |
| │ Robot │ | |
| │ GStreamer WebRTC daemon │ | |
| │ camera · mic · motors │ | |
| └─────────────────────────────────┘<!-- HTML_TAG_END --></pre></div> <ol data-svelte-h="svelte-90bqm6"><li><strong>Your app</strong> is a static HTML/JS page hosted on Hugging Face Spaces.</li> <li><strong>reachy-mini.js</strong> handles authentication, signaling, and WebRTC negotiation.</li> <li>The <strong>signaling server</strong> relays SDP offers/answers and ICE candidates. It also validates Hugging Face OAuth tokens.</li> <li>Once the WebRTC connection is established, <strong>video, audio, and commands flow peer-to-peer</strong> — the signaling server is no longer in the path.</li></ol> <h2 class="relative group"><a id="quick-start" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#quick-start"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Quick Start</span></h2> <h3 class="relative group"><a id="1-create-a-hugging-face-space" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#1-create-a-hugging-face-space"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>1. Create a Hugging Face Space</span></h3> <p data-svelte-h="svelte-a55rsv">Create a new Space on <a href="https://huggingface.co/new-space" rel="nofollow">huggingface.co</a> with <code>sdk: static</code>.</p> <p data-svelte-h="svelte-1djj17i">Your <code>README.md</code> front matter should look like:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">---</span> | |
| <span class="hljs-attr">title:</span> <span class="hljs-string">My</span> <span class="hljs-string">Reachy</span> <span class="hljs-string">Mini</span> <span class="hljs-string">App</span> | |
| <span class="hljs-attr">emoji:</span> <span class="hljs-string">🤖</span> | |
| <span class="hljs-attr">sdk:</span> <span class="hljs-string">static</span> | |
| <span class="hljs-attr">pinned:</span> <span class="hljs-literal">false</span> | |
| <span class="hljs-attr">hf_oauth:</span> <span class="hljs-literal">true</span> | |
| <span class="hljs-attr">hf_oauth_expiration_minutes:</span> <span class="hljs-number">480</span> | |
| <span class="hljs-meta">---</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-z1o929"><code>hf_oauth: true</code> is required — it enables the Hugging Face login button that the signaling server uses for authentication.</p> <h3 class="relative group"><a id="2-add-the-sdk" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#2-add-the-sdk"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>2. Add the SDK</span></h3> <p data-svelte-h="svelte-ol0zal">In your <code>index.html</code>, import the SDK as an ES module:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>></span><span class="language-javascript"> | |
| <span class="hljs-keyword">import</span> { <span class="hljs-title class_">ReachyMini</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"./reachy-mini.js"</span>; | |
| <span class="hljs-keyword">const</span> robot = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ReachyMini</span>(); | |
| </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-12fni1t">You can grab <code>reachy-mini.js</code> from the <a href="https://huggingface.co/spaces/cduss/webrtc_example" rel="nofollow">reference example</a> or from the npm CDN:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> { <span class="hljs-title class_">ReachyMini</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://cdn.jsdelivr.net/npm/@anthropic-robotics/reachy-mini/+esm"</span>;<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="3-connect-to-your-robot" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#3-connect-to-your-robot"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>3. Connect to your robot</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment">// Authenticate with Hugging Face</span> | |
| <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">await</span> robot.<span class="hljs-title function_">authenticate</span>()) { | |
| robot.<span class="hljs-title function_">login</span>(); <span class="hljs-comment">// redirects to HF login page</span> | |
| <span class="hljs-keyword">return</span>; | |
| } | |
| <span class="hljs-comment">// Connect to the signaling server</span> | |
| <span class="hljs-keyword">await</span> robot.<span class="hljs-title function_">connect</span>(); | |
| <span class="hljs-comment">// Wait for robots to appear</span> | |
| robot.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">"robotsChanged"</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =></span> { | |
| <span class="hljs-keyword">const</span> robots = e.<span class="hljs-property">detail</span>.<span class="hljs-property">robots</span>; | |
| <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"Available robots:"</span>, robots); | |
| }); | |
| <span class="hljs-comment">// Start a session with a specific robot</span> | |
| <span class="hljs-keyword">const</span> detach = robot.<span class="hljs-title function_">attachVideo</span>(<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">"video"</span>)); | |
| <span class="hljs-keyword">await</span> robot.<span class="hljs-title function_">startSession</span>(robotId); | |
| <span class="hljs-comment">// You're live — video is streaming, data channel is open</span><!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="4-control-the-robot" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#4-control-the-robot"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>4. Control the robot</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment">// Move the head (roll, pitch, yaw in degrees)</span> | |
| robot.<span class="hljs-title function_">setHeadPose</span>(<span class="hljs-number">0</span>, <span class="hljs-number">10</span>, -<span class="hljs-number">5</span>); | |
| <span class="hljs-comment">// Move the antennas (right, left in degrees)</span> | |
| robot.<span class="hljs-title function_">setAntennas</span>(<span class="hljs-number">30</span>, -<span class="hljs-number">30</span>); | |
| <span class="hljs-comment">// Play a sound file on the robot</span> | |
| robot.<span class="hljs-title function_">playSound</span>(<span class="hljs-string">"wake_up.wav"</span>); | |
| <span class="hljs-comment">// Send any JSON command via the data channel</span> | |
| robot.<span class="hljs-title function_">sendRaw</span>({ <span class="hljs-attr">my_custom_command</span>: <span class="hljs-string">"hello"</span> });<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="5-receive-robot-state" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#5-receive-robot-state"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>5. Receive robot state</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment">// Emitted every ~500ms while streaming</span> | |
| robot.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">"state"</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =></span> { | |
| <span class="hljs-keyword">const</span> { head, antennas } = e.<span class="hljs-property">detail</span>; | |
| <span class="hljs-comment">// head: { roll, pitch, yaw } — degrees</span> | |
| <span class="hljs-comment">// antennas: { right, left } — degrees</span> | |
| });<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="6-audio" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#6-audio"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>6. Audio</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment">// Unmute robot speaker (muted by default in browser)</span> | |
| robot.<span class="hljs-title function_">setAudioMuted</span>(<span class="hljs-literal">false</span>); | |
| <span class="hljs-comment">// Unmute your microphone (bidirectional audio, if robot supports it)</span> | |
| robot.<span class="hljs-title function_">setMicMuted</span>(<span class="hljs-literal">false</span>); | |
| <span class="hljs-comment">// Check if bidirectional audio is available</span> | |
| robot.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">"micSupported"</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =></span> { | |
| <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"Mic supported:"</span>, e.<span class="hljs-property">detail</span>.<span class="hljs-property">supported</span>); | |
| });<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="7-cleanup" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#7-cleanup"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>7. Cleanup</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-title function_">detach</span>(); <span class="hljs-comment">// remove video binding</span> | |
| <span class="hljs-keyword">await</span> robot.<span class="hljs-title function_">stopSession</span>(); <span class="hljs-comment">// back to 'connected' state</span> | |
| robot.<span class="hljs-title function_">disconnect</span>(); <span class="hljs-comment">// close signaling (keeps auth)</span> | |
| robot.<span class="hljs-title function_">logout</span>(); <span class="hljs-comment">// clear HF credentials</span><!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="api-reference" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#api-reference"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>API Reference</span></h2> <h3 class="relative group"><a id="constructor" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#constructor"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Constructor</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">new</span> <span class="hljs-title class_">ReachyMini</span>({ | |
| <span class="hljs-attr">signalingUrl</span>: <span class="hljs-string">"https://cduss-reachy-mini-central.hf.space"</span>, <span class="hljs-comment">// default</span> | |
| <span class="hljs-attr">enableMicrophone</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// default — request mic on startSession()</span> | |
| })<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="state-machine" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#state-machine"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>State Machine</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-string">'disconnected'</span> ──<span class="hljs-function"><span class="hljs-title">connect</span>()──▸ <span class="hljs-string">'connected'</span> ──<span class="hljs-title">startSession</span>()──▸ <span class="hljs-string">'streaming'</span> | |
| ▴ <span class="hljs-title">disconnect</span>() ▴ <span class="hljs-title">stopSession</span>()</span> | |
| └─────────────────────────────┘<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="properties-read-only" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#properties-read-only"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Properties (read-only)</span></h3> <table data-svelte-h="svelte-1yeqs0x"><thead><tr><th align="left">Property</th> <th align="left">Type</th> <th align="left">Description</th></tr></thead> <tbody><tr><td align="left"><code>state</code></td> <td align="left"><code>string</code></td> <td align="left"><code>"disconnected"</code>, <code>"connected"</code>, or <code>"streaming"</code></td></tr> <tr><td align="left"><code>robots</code></td> <td align="left"><code>Array</code></td> <td align="left">Available robots: <code>[{ id, meta: { name } }]</code></td></tr> <tr><td align="left"><code>robotState</code></td> <td align="left"><code>Object</code></td> <td align="left"><code>{ head: { roll, pitch, yaw }, antennas: { right, left } }</code> (degrees)</td></tr> <tr><td align="left"><code>username</code></td> <td align="left"><code>string\|null</code></td> <td align="left">HF username after <code>authenticate()</code></td></tr> <tr><td align="left"><code>isAuthenticated</code></td> <td align="left"><code>boolean</code></td> <td align="left">True if a valid HF token is available</td></tr> <tr><td align="left"><code>micSupported</code></td> <td align="left"><code>boolean</code></td> <td align="left">True if robot offers bidirectional audio</td></tr> <tr><td align="left"><code>micMuted</code></td> <td align="left"><code>boolean</code></td> <td align="left">Your microphone mute state</td></tr> <tr><td align="left"><code>audioMuted</code></td> <td align="left"><code>boolean</code></td> <td align="left">Robot speaker mute state (local only)</td></tr></tbody></table> <h3 class="relative group"><a id="methods" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#methods"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Methods</span></h3> <table data-svelte-h="svelte-5mvcda"><thead><tr><th align="left">Method</th> <th align="left">Returns</th> <th align="left">Description</th></tr></thead> <tbody><tr><td align="left"><code>authenticate()</code></td> <td align="left"><code>Promise<boolean></code></td> <td align="left">Check for existing HF OAuth token</td></tr> <tr><td align="left"><code>login()</code></td> <td align="left">—</td> <td align="left">Redirect to HF login page</td></tr> <tr><td align="left"><code>connect()</code></td> <td align="left"><code>Promise</code></td> <td align="left">Open SSE connection, receive robot list</td></tr> <tr><td align="left"><code>startSession(robotId)</code></td> <td align="left"><code>Promise</code></td> <td align="left">Negotiate WebRTC, resolves when video + data ready</td></tr> <tr><td align="left"><code>stopSession()</code></td> <td align="left"><code>Promise</code></td> <td align="left">End session, back to <code>connected</code></td></tr> <tr><td align="left"><code>disconnect()</code></td> <td align="left">—</td> <td align="left">Close signaling (keeps auth)</td></tr> <tr><td align="left"><code>logout()</code></td> <td align="left">—</td> <td align="left">Clear HF credentials</td></tr> <tr><td align="left"><code>attachVideo(videoEl)</code></td> <td align="left"><code>() => void</code></td> <td align="left">Bind video stream to element; returns cleanup function</td></tr> <tr><td align="left"><code>setHeadPose(roll, pitch, yaw)</code></td> <td align="left"><code>boolean</code></td> <td align="left">Set head orientation in degrees</td></tr> <tr><td align="left"><code>setAntennas(right, left)</code></td> <td align="left"><code>boolean</code></td> <td align="left">Set antenna positions in degrees</td></tr> <tr><td align="left"><code>playSound(filename)</code></td> <td align="left"><code>boolean</code></td> <td align="left">Play a sound file on the robot</td></tr> <tr><td align="left"><code>sendRaw(data)</code></td> <td align="left"><code>boolean</code></td> <td align="left">Send arbitrary JSON via data channel</td></tr> <tr><td align="left"><code>requestState()</code></td> <td align="left"><code>boolean</code></td> <td align="left">Request a state snapshot</td></tr> <tr><td align="left"><code>setAudioMuted(muted)</code></td> <td align="left">—</td> <td align="left">Mute/unmute robot speaker (local)</td></tr> <tr><td align="left"><code>setMicMuted(muted)</code></td> <td align="left">—</td> <td align="left">Mute/unmute your microphone</td></tr></tbody></table> <h3 class="relative group"><a id="events" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#events"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Events</span></h3> <p data-svelte-h="svelte-fsgll3">Use <code>robot.addEventListener(name, handler)</code> — the SDK extends <code>EventTarget</code>.</p> <table data-svelte-h="svelte-iboe9z"><thead><tr><th align="left">Event</th> <th align="left">Detail</th> <th align="left">Description</th></tr></thead> <tbody><tr><td align="left"><code>connected</code></td> <td align="left"><code>{ peerId }</code></td> <td align="left">Signaling connection established</td></tr> <tr><td align="left"><code>disconnected</code></td> <td align="left"><code>{ reason }</code></td> <td align="left">Signaling connection lost</td></tr> <tr><td align="left"><code>robotsChanged</code></td> <td align="left"><code>{ robots }</code></td> <td align="left">Robot list updated</td></tr> <tr><td align="left"><code>streaming</code></td> <td align="left"><code>{ sessionId, robotId }</code></td> <td align="left">WebRTC session active</td></tr> <tr><td align="left"><code>sessionStopped</code></td> <td align="left"><code>{ reason }</code></td> <td align="left">Session ended</td></tr> <tr><td align="left"><code>state</code></td> <td align="left"><code>{ head, antennas }</code></td> <td align="left">Robot state update (~500ms)</td></tr> <tr><td align="left"><code>videoTrack</code></td> <td align="left"><code>{ track, stream }</code></td> <td align="left">Video track available</td></tr> <tr><td align="left"><code>micSupported</code></td> <td align="left"><code>{ supported }</code></td> <td align="left">Bidirectional audio availability</td></tr> <tr><td align="left"><code>error</code></td> <td align="left"><code>{ source, error }</code></td> <td align="left">Error from <code>signaling</code>, <code>webrtc</code>, or <code>robot</code></td></tr></tbody></table> <h3 class="relative group"><a id="math-utilities" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#math-utilities"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Math Utilities</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> { rpyToMatrix, matrixToRpy, degToRad, radToDeg } <span class="hljs-keyword">from</span> <span class="hljs-string">"./reachy-mini.js"</span>; | |
| <span class="hljs-title function_">rpyToMatrix</span>(roll, pitch, yaw) <span class="hljs-comment">// degrees → 4×4 rotation matrix (ZYX)</span> | |
| <span class="hljs-title function_">matrixToRpy</span>(matrix) <span class="hljs-comment">// 4×4 matrix → { roll, pitch, yaw } in degrees</span><!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="security" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#security"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Security</span></h2> <ul data-svelte-h="svelte-1eoh024"><li>Authentication goes through Hugging Face OAuth — only users logged in to HF can access the signaling server.</li> <li>By default, you can only connect to robots registered under your own HF account.</li> <li>WebRTC connections are encrypted (DTLS/SRTP).</li></ul> <h2 class="relative group"><a id="prerequisites" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#prerequisites"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Prerequisites</span></h2> <ul data-svelte-h="svelte-b674ie"><li>Your robot must be running the wireless firmware and connected to the central signaling server.</li> <li>The robot must have a valid Hugging Face token configured (see <a href="../platforms/reachy_mini/usage">Usage</a>).</li> <li>Currently supported on <strong>wireless versions</strong> only.</li></ul> <h2 class="relative group"><a id="example" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#example"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Example</span></h2> <p data-svelte-h="svelte-1dkgil8">A full working example is available as a Hugging Face Space: | |
| <a href="https://huggingface.co/spaces/cduss/webrtc_example" rel="nofollow">cduss/webrtc_example</a></p> <p data-svelte-h="svelte-1parfz0">It demonstrates video streaming, head/antenna control, bidirectional audio, and sound playback — all from a single static HTML page.</p> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/pollen-robotics/reachy_mini/blob/main/docs/source/SDK/javascript-sdk.md" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg> <span data-svelte-h="svelte-zjs2n5"><span class="underline">Update</span> on GitHub</span></a> <p></p> | |
| <script> | |
| { | |
| __sveltekit_11b5lrv = { | |
| assets: "/docs/reachy_mini/pr_970/en", | |
| base: "/docs/reachy_mini/pr_970/en", | |
| env: {} | |
| }; | |
| const element = document.currentScript.parentElement; | |
| const data = [null,null]; | |
| Promise.all([ | |
| import("/docs/reachy_mini/pr_970/en/_app/immutable/entry/start.af5bca3c.js"), | |
| import("/docs/reachy_mini/pr_970/en/_app/immutable/entry/app.7a7af01f.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 14], | |
| data, | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 65.9 kB
- Xet hash:
- 1dff8a28ffb7c5ebe4cbf4b84010fa853b03d50b7e3eafa05e7a75fceb71d6af
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.