How to Test a Game Controller in Your Browser with the Gamepad API

in #gaming4 days ago

If you game on a PC, you have probably wondered whether a drifting stick or a dead button is the controller's fault or the game's. You do not need to install anything to find out — modern browsers expose the Gamepad API, and a few lines of JavaScript can read every axis and button in real time.

Reading a gamepad in the browser

When a controller is connected and you press a button, the browser fires a gamepadconnected event. From there you poll the state on each animation frame:

window.addEventListener("gamepadconnected", (e) => {
  console.log("connected:", e.gamepad.id);
  requestAnimationFrame(poll);
});

function poll() {
  const gp = navigator.getGamepads()[0];
  if (gp) {
    // axes: left stick X/Y, right stick X/Y, range -1..1
    console.log(gp.axes.map(a => a.toFixed(3)).join(", "));
    // buttons: pressed + analog value (triggers)
    gp.buttons.forEach((b, i) => {
      if (b.pressed) console.log("button", i, b.value.toFixed(2));
    });
  }
  requestAnimationFrame(poll);
}

That is the whole core loop. Everything a controller-testing tool does is built on top of those two arrays: axes for the sticks and triggers, buttons for everything you press.

What is actually worth checking

  • Buttons — every face button, bumper, d-pad direction and stick click should register once, with no ghost presses.
  • Triggers — these are analog. A healthy trigger sweeps smoothly from 0.00 to 1.00; a worn one jumps or never reaches the ends.
  • Sticks — at rest both axes should sit near 0. If the numbers wander while you are not touching the stick, that is drift.
  • Rumble — the API can also trigger the vibration motors, which is the only way to confirm both motors still fire.

Stick drift, specifically

Drift is the most common controller failure, and the raw axis data makes it obvious. Let go of the stick and watch the values: a resting offset of a few hundredths is normal deadzone noise, but a steady reading like 0.18 with the stick centered means the potentiometer is worn. Plotting the stick position over a few seconds turns this into a picture you can actually read — that is what a dedicated stick drift test does, so you do not have to stare at numbers.

I put together a small browser-based Controller Tester that visualizes all of this — sticks, buttons, triggers and rumble — with nothing to install, because the Gamepad API already ships in every Chromium and Firefox build. If you are debugging a controller before a return window closes, reading the raw values yourself is genuinely the fastest check.

Happy to answer questions about the Gamepad API in the comments.