Browser hardware diagnostics. Plug something in and test it — controllers, monitors, graphics adapters, speakers, microphones, keyboards and mice.
Everything runs client-side. No install, no account, no backend, and nothing is uploaded: the app stores no cookies and no local data of any kind.
| What it finds | |
|---|---|
| Gamepad | Four slots, live button and axis readouts, a layout diagram that lights up, stick circularity and resting drift analysis, analog trigger travel, and dual-rumble / trigger-rumble tests. Names pads from their USB vendor and product id — PlayStation, Xbox, Nintendo, 8BitDo, Logitech and more. |
| Display | Full-screen patterns for dead and stuck pixels, backlight bleed and IPS glow, colour banding, crushed blacks and blown highlights, ghosting and overdrive overshoot, and scaling or sharpness problems. |
| GPU | The real adapter behind WebGL and WebGPU, its limits and extensions, measured display refresh rate, and a scalable shader load reporting average FPS, 1% lows and a frame-time plot. |
| Speakers | Left/right channel isolation, a 20 Hz → 20 kHz logarithmic sweep with a live frequency readout, a tone generator with four waveforms plus white and pink noise, a stepped range check, and a per-channel output meter. |
| Mic | Live waveform, frequency spectrum and a dBFS level meter with peak hold and clipping detection. Device switching, AEC / noise-suppression / auto-gain toggles, and a local recording to play back. |
| Keyboard | A full-size board that lights up per key with a tested/untested tally, switchable between QWERTY (US ANSI, 104 keys) and AZERTY (French ISO, 105 keys), n-key rollover measurement, and a raw code / key / keyCode event log. |
| Mouse | Five-button map, scroll-wheel deltas, a movement trail, true report rate measured from coalesced pointer samples, and switch-chatter detection for the double-click fault. |
npm install
npm run devThen open http://localhost:3000.
npm run build produces a fully static export — every route prerenders, because
all measurement happens in the browser.
Serve it over HTTPS if you host it. The mic tester uses
getUserMedia, which requires a secure context.localhostis exempt, so local development is fine, but opening the app over plain HTTP from another machine will break it.
Index — every tester in one hairline grid
Keyboard — held keys in amber, tested keys in green, live rollover count
Display — six full-screen pattern sets, each opening fullscreen
Speakers — channel check, frequency sweep and per-channel output meter
A few things that are easy to get wrong, and how this handles them:
- Gamepads stay invisible until you press something. That is a browser rule,
not a bug. Chromium also hands out immutable snapshots, so a stored
Gamepadobject never updates — the API has to be re-read every animation frame. - Stick circularity bins the outer travel by angle and reports the spread between the shortest and longest reach. A partial sweep cannot prove roundness, so angular coverage scales the score rather than faking a result.
- GPU frame rate is capped by vsync. A healthy adapter sits pinned at the refresh rate until the shader load outgrows it. Raise the iterations until the average drops — that is where the GPU, not vsync, is deciding the frame time.
- Mouse report rate comes from
getCoalescedEvents(), which carries every sample the device sent between frames. That is how it reads the full 1000 Hz of a gaming mouse rather than the 60 Hz the page repaints at. - Click chatter is a press shorter than 15 ms, or two presses inside 60 ms — the fault behind a mouse that double-clicks on its own.
- Keyboard layout switching changes legends, not codes.
KeyboardEvent.codealways names the physical switch, so the key marked Z on AZERTY still reportsKeyW. The ISO board is a different shape though: tall Enter, shortened left Shift, and anIntlBackslashkey that ANSI has no position for. - The speaker output meter reads the audio graph, not the speakers. If the bars move and you hear nothing, the fault is downstream of the browser — wrong output device, muted mixer channel, or the speakers themselves.
Next.js 16 (App Router) · React 19 · TypeScript · Tailwind CSS 4.
No runtime dependencies beyond the framework. Every tester sits directly on a browser API — Gamepad, WebGL/WebGPU, Web Audio, Pointer Events, Fullscreen.
Text contrast meets WCAG AA throughout, and no page scrolls horizontally at 375 px.
MIT © Mohamed Ali Jemmali




