CTRLLR Documentation
Welcome to CTRLLR — turn phones into game controllers for your web app.
What is CTRLLR?
Players scan a QR code with the CTRLLR mobile app and their phone becomes a
low-latency gamepad, streamed to your page over a peer-to-peer WebRTC data
channel. @ctrllr/sdk gives you a simple, type-safe API on top: connected
controllers, live input state, and edge-detected button events. One phone is a
single-player controller; several phones make instant couch multiplayer.
The controller
Every connected phone gives you the same layout:
- Joystick — analog stick,
x/yin-1..1 - A, X, Y, Z — four aimable action buttons: besides
pressed, each reports anx/ydisplacement while held, so a single button can shoot and aim - Start — a simple press-only button
Features
- No extra hardware — controllers are the phones already in the room
- Peer-to-peer input — WebRTC data channels; the signaling server only brokers the connection
- TypeScript first — fully typed state, events, and payloads
- Framework agnostic — a plain event-emitting manager; works with React, Vue, vanilla JS, or a canvas game loop
- Multiplayer by default — controllers get stable indexes (
0, 1, 2…); a freed index is handed back on reconnect
Quick Example
import { CtrllrManager } from '@ctrllr/sdk';
const ctrllr = new CtrllrManager({ signalingUrl: '...' });
await ctrllr.connect();
ctrllr.on('controllerconnected', ({ controller }) => {
console.log(`P${controller.index + 1} (${controller.username}) joined`);
controller.on('buttondown', (e) => {
if (e.input === 'a') fire(e.x, e.y); // aimable: direction included
});
controller.on('statechange', ({ state }) => {
move(state.joystick.x, state.joystick.y);
});
});
Want to feel it first? Play CTRLLR Invaders — then open the Debugger to watch the raw input stream.
Ready to dive in? Head to the Getting Started guide.