Gamepad API for developers

The tester on this site is a thin reader of the Gamepad API. If you are wiring a game or a web page, the rules below are the ones that keep the indexes and the hertz figure honest.

Poll on animation frames

The connect event fires when a button is pressed. It does not stream axes. Read the list inside requestAnimationFrame and stop the loop when the tab is hidden.

const pads = navigator.getGamepads();
// Call this inside requestAnimationFrame.
// pads is a sparse array. Check connected before you read buttons.

Standard button indexes

Use these only when `mapping === "standard"`. Otherwise show numbers.

IndexControl
0–3South, east, west, north face
4–5Left bumper, right bumper
6–7Left trigger, right trigger (analog)
8–9Back / Create, Start / Options
10–11Left stick click, right stick click
12–15D-pad up, down, left, right
16–17Guide, touchpad click when present

Axes 0 and 1 are the left stick. Axes 2 and 3 are the right stick. Positive Y is usually down. Extra axes belong in a raw list, not in the right-stick plot.

Timestamps and hertz

`gamepad.timestamp` updates when the browser accepts a new sample. Median gaps between timestamps are a delivery rate. Subtracting the timestamp from `performance.now()` is sample age when both clocks match. Label both figures as browser-observed. Shipping a “1000 Hz” badge from this math is how tester pages mislead people.

Vibration

Call `vibrationActuator.playEffect("dual-rumble", { duration, strongMagnitude, weakMagnitude })` and handle rejection. `"trigger-rumble"` is a Chromium extension with left and right trigger magnitudes. There is no standard call for adaptive trigger resistance or DualSense voice-coil haptics.

WebHID

Treat WebHID as a separate permission, desktop Chromium only, and do not write output reports unless you have a tested parser and a recovery path. This site’s gyro button requests Sony vendor 0x054C, reads the product name, and closes the device. The MDN pages for the Gamepad API and WebHID are the specs. This page is the part we actually run.