Skip to content

Repository files navigation

HardwareProbe

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.

Gamepad tester showing a connected DualShock 4 with live button, stick and trigger readouts


Testers

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.

Running it

npm install
npm run dev

Then 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. localhost is exempt, so local development is fine, but opening the app over plain HTTP from another machine will break it.

Screenshots

Index — every tester in one hairline grid

The tester index

Keyboard — held keys in amber, tested keys in green, live rollover count

Keyboard tester with keys held and tested

Display — six full-screen pattern sets, each opening fullscreen

Display tester pattern list

Speakers — channel check, frequency sweep and per-channel output meter

Speaker tester with channel check and sweep

How the measurements work

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 Gamepad object 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.code always names the physical switch, so the key marked Z on AZERTY still reports KeyW. The ISO board is a different shape though: tall Enter, shortened left Shift, and an IntlBackslash key 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.

Stack

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.

Licence

MIT © Mohamed Ali Jemmali

About

Browser-based hardware diagnostics. Test controllers, monitors, GPUs, speakers, microphones, keyboards and mice with live readouts — stick drift and circularity, dead pixels, frame-time, channel isolation, n-key rollover, mouse polling rate. No install, no backend, nothing uploaded.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages