Like most beginner web developers, I spent a lot of time following tutorials and building “to-do apps” that never made it beyond my own computer. They were good practice, but I wanted to build something real that people could actually use.
That’s how I ended up creating gamepad tester a small web tool that lets you check whether your game controller is working properly right in the browser.
The Idea
The inspiration came from frustration. I plugged in my Xbox controller one day, and it just wasn’t behaving right in a game. Was it the controller, the USB cable, or the game itself?
I thought: Wouldn’t it be great to have a quick online tool that tells me if all buttons and sticks are responding?
Turns out the browser already has a neat feature for this: the HTML5 Gamepad API. That was enough to spark the project.
Building the Tool
I didn’t overcomplicate it. Just HTML, CSS, and JavaScript.
Here’s a simplified version of the core script that detects and displays button presses and stick movement:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Gamepad Tester</title>
<style>
body { font-family: sans-serif; }
.button {
display: inline-block;
width: 40px; height: 40px;
margin: 5px; text-align: center; line-height: 40px;
border: 1px solid #333; border-radius: 8px;
}
.pressed { background: #4caf50; color: white; }
</style>
</head>
<body>
<h2>Press any button on your controller to start</h2>
<div id="buttons"></div>
<script>
let controllers = {};
function connectHandler(e) {
addGamepad(e.gamepad);
}
function addGamepad(gamepad) {
controllers[gamepad.index] = gamepad;
const buttonsDiv = document.getElementById("buttons");
buttonsDiv.innerHTML = "";
gamepad.buttons.forEach((btn, i) => {
const b = document.createElement("div");
b.className = "button";
b.innerText = i;
buttonsDiv.appendChild(b);
});
requestAnimationFrame(updateStatus);
}
function updateStatus() {
scanGamepads();
for (let j in controllers) {
const controller = controllers[j];
const buttons = document.getElementById("buttons").children;
controller.buttons.forEach((btn, i) => {
if (btn.pressed) {
buttons[i].classList.add("pressed");
} else {
buttons[i].classList.remove("pressed");
}
});
}
requestAnimationFrame(updateStatus);
}
function scanGamepads() {
const gamepads = navigator.getGamepads();
for (let i = 0; i < gamepads.length; i++) {
if (gamepads[i]) controllers[gamepads[i].index] = gamepads[i];
}
}
window.addEventListener("gamepadconnected", connectHandler);
</script>
</body>
</html>
Open this in your browser, plug in a controller, and you will see the buttons light up when pressed. It’s a very stripped-down version of what I later turned into gamepadtest.com but the principle is the same.
What I Learned
• Start small: You don’t need React, a backend, or a database to make something useful.
• APIs are fun: Browsers can do more than you think. The Gamepad API was surprisingly powerful once I understood it.
• Feedback is gold: Friends tested it and pointed out things I never thought of, like displaying joystick axes.
• Shipping feels amazing: Even though it was a small project, publishing it online felt better than any tutorial app I had ever built.
Building my first web tool taught me that it’s not about making something huge or perfect. It’s about making something useful, no matter how small.
If you want to try out the full version I built, check out gamepad tester. It might save you some frustration the next time your controller acts up.
Top comments (2)
Well
Very cool! I didn't know about this built in browser functionality with such wide support.