v147 · web api · in developer trial
Gamepad Event-Driven Input API
An extension to the Gamepad API that fires a rawgamepadinputchange event whenever new input data arrives from the device, eliminating the need to poll navigator.getGamepads() on every animation frame. Reduces input latency for games and interactive applications that care about sub-frame responsiveness.
chrome://flags/#enable-experimental-web-platform-features to test it. The event name and interface shape may change before shipping.
at a glance
| Status in Chrome 147 | In developer trial (behind a flag) |
|---|---|
| Flag | chrome://flags/#enable-experimental-web-platform-features |
| New event | rawgamepadinputchange on window |
| Standards position | Firefox: No signal (experimental implementation exists) · Safari: No signal |
| Spec | W3C Gamepad spec (working draft) |
| Chromium bug | crbug.com/40582297 |
| Demo | gabrielsanbrito.github.io/gamepad-raw-input-events |
| ChromeStatus | 5989275208253440 — Gamepad Event-Driven Input API |
why it exists
The existing Gamepad API requires polling: you call navigator.getGamepads() inside a requestAnimationFrame loop, which runs at most at the display refresh rate (typically 60 Hz). A gamepad can report input at 1000 Hz or higher. The gap means input events can be 1–16 ms stale before the application sees them — unacceptable in competitive games or precision controllers. An event-driven model fires immediately when the hardware reports new data, independently of the frame rate, enabling applications to respond at the device's native rate.
shape of the API
One new event on window that fires for every hardware input report:
rawgamepadinputchange event
| Target | window |
|---|---|
| Fires when | The gamepad hardware reports new button or axis data, at the device's native polling rate — independent of requestAnimationFrame. |
event.gamepad | A snapshot Gamepad object with the current button and axis state at the time of the report. |
event.gamepad.index | Index matching the existing navigator.getGamepads() array. |
event.gamepad.buttons | Array of GamepadButton objects with pressed, touched, and value. |
event.gamepad.axes | Array of axis values in the range [-1, 1]. |
event.gamepad.timestamp | High-resolution timestamp of the hardware report. |
example
Event-driven input loop (replaces polling)
// Previously: polling inside rAF
function pollLoop() {
const gamepads = navigator.getGamepads();
if (gamepads[0]) {
handleInput(gamepads[0]);
}
requestAnimationFrame(pollLoop);
}
// With rawgamepadinputchange: fires at device rate, not frame rate
window.addEventListener('rawgamepadinputchange', (event) => {
handleInput(event.gamepad);
});
Low-latency button handler
window.addEventListener('rawgamepadinputchange', (event) => {
const { gamepad } = event;
// A button (index 0) — fire at native device rate
if (gamepad.buttons[0].pressed) {
triggerAction(gamepad.index, 'A', gamepad.timestamp);
}
// Left stick X axis
const leftX = gamepad.axes[0];
if (Math.abs(leftX) > 0.1) {
moveCharacter(leftX);
}
});
Source: W3C Gamepad API spec and feature summary, May 2026.
relation to the existing Gamepad API
Polling model (navigator.getGamepads()) | Still works. Returns snapshot at rAF rate. Good for most games; no changes needed. |
|---|---|
rawgamepadinputchange events | Fires at hardware rate. Use when latency or missed inputs at sub-frame granularity matter. |
gamepadconnected / gamepaddisconnected | Unchanged. Still the mechanism for detecting connect/disconnect. |
browser support
| Browser | Support |
|---|---|
| Chrome 147 | In developer trial (behind flag) |
| Edge 147 | Tracking Chromium |
| Firefox | No signal (experimental internal implementation exists) |
| Safari | No signal |
see also
- chromestatus — Gamepad Event-Driven Input API (5989275208253440)
- W3C Gamepad spec (working draft)
- Chromium bug — crbug.com/40582297
- Live demo: gamepad raw input events
- w3c/gamepad issue #4 — long-running request for gamepad events
- chrome-platform-showcase: Gamepad Event-Driven Input API demos (when built)