JavaScript Navigator getGamepads() Method

Beginner
5 min read
Updated: Nov 2026
5 examples
Method

Definition

navigator.getGamepads() returns an array of Gamepad objects — one slot per connected controller (MDN). Slots may be null after a disconnect so other pads keep the same index.

Pass the required arguments shown below. Check return values and browser support before you rely on the result.

Syntax

Call navigator.getGamepads. Start with this line.

JavaScript
navigator.getGamepads()
CallWhat it does
navigator.getGamepads()Primary signature.
navigator.getGamepads(...)Call with the arguments your case needs.

Built into the browser. Call getGamepads(...) on a Navigator — no import required.

Library declarations
JavaScript
navigator.getGamepads()

Parameters

This member has no parameters beyond those shown in the signature.

Return Value

Return ValueDescription
*Gamepad[] (may contain null)

JavaScript Examples

Example 1 — Feature Detection

Check whether getGamepads exists before using the Gamepad API.

JavaScript
const lines = [
  "getGamepads: " +
    (typeof navigator.getGamepads === "function" ? "available" : "missing"),
  "slots: " +
    (typeof navigator.getGamepads === "function"
      ? navigator.getGamepads().length
      : "n/a")
];
console.log(lines.join("\n"));
Try It Yourself

How It Works

  1. Test the method. Baseline browsers expose getGamepads as a function.
  2. Call for slot count. Length can be 0 before any pad is activated.
  3. Empty ≠ broken. Press a button on the controller to activate it.
  4. Then list pads. Only after activation will non-null entries appear.

Example 2 — List Connected Pads (Skip null)

Filter out empty index holes before displaying controllers.

JavaScript
function listConnectedPads() {
  if (!navigator.getGamepads) return ["getGamepads not supported"];
  const pads = Array.from(navigator.getGamepads()).filter(Boolean);
  if (!pads.length) return ["No active gamepads (press a button on your controller)"];
  return pads.map(
    (gp) =>
      "#" + gp.index + " " + gp.id +
      " | buttons=" + gp.buttons.length +
      " axes=" + gp.axes.length
  );
}

console.log(listConnectedPads().join("\n"));
Try It Yourself

How It Works

  1. Snapshot the array. Array.from turns the result into a normal array.
  2. Drop null. filter(Boolean) keeps only real pads.
  3. Map a short label. Index, id, button count, and axis count.
  4. Guide the user. If empty, ask them to press a button on the pad.

Example 3 — gamepadconnected (MDN)

MDN pattern: on connect, re-read the pad from getGamepads() by index.

JavaScript
window.addEventListener("gamepadconnected", (e) => {
  const gp = navigator.getGamepads()[e.gamepad.index];
  console.log(
    "Gamepad connected at index " + gp.index + ": " + gp.id +
    " with " + gp.buttons.length + " buttons, " + gp.axes.length + " axes."
  );
});

console.log("Listening for gamepadconnected — press a button on your pad");
Try It Yourself

How It Works

  1. Subscribe on window. Connect/disconnect events are window-level.
  2. Use the event index. e.gamepad.index points at the slot.
  3. Re-fetch from getGamepads(). MDN reads the live object from the array.
  4. Also handle disconnect. Listen for gamepaddisconnected to clear UI.

Example 4 — Read Buttons & Axes

Inspect the first connected pad’s primary button and stick axes.

JavaScript
function describeFirstPad() {
  if (!navigator.getGamepads) return "getGamepads not supported";
  const gp = Array.from(navigator.getGamepads()).find(Boolean);
  if (!gp) return "No active gamepad";
  const btn0 = gp.buttons[0];
  return [
    "id: " + gp.id,
    "button0.pressed: " + (btn0 ? btn0.pressed : "n/a"),
    "button0.value: " + (btn0 ? btn0.value : "n/a"),
    "axes: [" + gp.axes.map((a) => a.toFixed(2)).join(", ") + "]"
  ].join("\n");
}

console.log(describeFirstPad());
Try It Yourself

How It Works

  1. Find the first real pad. find(Boolean) skips null slots.
  2. Read pressed. Digital buttons are usually true/false.
  3. Read value. Analog triggers often use 0–1 pressure.
  4. Format axes. Stick positions are typically in the −1…1 range.

Example 5 — Simple Poll Loop Sketch

Beginner game-loop pattern: poll pads each animation frame.

JavaScript
let frames = 0;

function pollGamepads() {
  frames += 1;
  const pads = navigator.getGamepads
    ? Array.from(navigator.getGamepads()).filter(Boolean)
    : [];
  if (frames <= 3) {
    console.log("frame " + frames + " pads=" + pads.length);
  }
  if (frames < 3) {
    requestAnimationFrame(pollGamepads);
  } else {
    console.log("Stopped demo poll after 3 frames");
  }
}

requestAnimationFrame(pollGamepads);
Try It Yourself

How It Works

  1. Schedule with rAF. Matches the display refresh for smooth games.
  2. Re-call getGamepads(). Each frame needs a fresh snapshot.
  3. Count active pads. Filter out null before using length.
  4. Stop the demo. Real games keep polling while the scene is active.

Browser Support

navigator.getGamepads() is part of the Gamepad API and is Baseline Widely available since March 2017. Controllers often need a button press before they appear in the array. A Permissions Policy can still block access.

✓ Baseline · Widely available

Navigator.getGamepads()

Snapshot array of Gamepad objects — poll for live buttons and axes.

95% Modern browser support
Google Chrome Gamepad API · Baseline
Supported
Microsoft Edge Gamepad API · Baseline
Supported
Apple Safari Gamepad API · Baseline
Supported
Opera Gamepad API · Baseline
Supported
Mozilla Firefox Gamepad API · Baseline
Supported
Internet Explorer No Gamepad API
Unavailable
getGamepads() Excellent

Bottom line: Safe for modern web games. Listen for gamepadconnected, skip null slots, and poll getGamepads() in your animation loop.

Frequently Asked Questions

It returns an array of Gamepad objects for controllers connected to the device. Some slots may be null if a pad disconnected, so remaining pads keep the same index.
No. MDN marks it Baseline Widely available (since March 2017). It is not Deprecated, Experimental, or Non-standard — no status banner is required.
Many browsers only expose gamepads after the user presses a button on the controller (privacy / gesture). Listen for gamepadconnected, then call getGamepads().
If a gamepad disconnects mid-session, its slot may become null so other pads keep stable indexes. Always skip null entries when looping.
Use gamepad.buttons (pressed / value) and gamepad.axes (usually -1 to 1). Poll getGamepads() each animation frame for continuous input.
Yes. A SecurityError can be thrown if use is blocked by a Permissions Policy.

Next: getInstalledRelatedApps()

Learn how to detect related installed apps and PWAs from the page.

getInstalledRelatedApps() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

9 people found this page helpful