About this spacebar counter

A small, fast, dependency-free tool for one job: counting real spacebar presses and, in timed mode, turning that into a presses-per-second score. No account, no upload, nothing you press is ever recorded anywhere but on your own device.

Why it exists

People end up wanting to count spacebar presses for reasons that have almost nothing in common with each other: a game or meme challenge built around raw speed, curiosity about how fast you can tap, or a genuinely practical question — is this laptop's spacebar starting to fail, is it double-firing, is it missing presses under a worn key? All three deserve a tool that counts exactly what happened and nothing else, which turns out to be less trivial than it sounds, because of key-repeat.

Any time you hold a key down for more than a fraction of a second, your operating system starts firing synthetic repeat keydowns on its own — the same mechanism that makes a held Backspace delete a whole line. A counter that doesn't account for that will report wildly inflated numbers the instant someone holds the bar instead of tapping it, and will do so silently, which is worse than being wrong loudly.

How the counting and timing are implemented

  • Key-repeat is filtered before anything else runs. Every keydown handler checks event.repeat first and returns immediately if it's true. Only the first keydown of a physical press-and-release cycle ever reaches the counting logic.
  • The key is identified by event.code, not event.key. event.code reports the physical key ("Space") regardless of keyboard layout or modifier state, which is the more reliable signal for "did the spacebar move."
  • preventDefault() runs on every accepted Space keydown so the page itself never scrolls while you're testing — the default browser behaviour for Space on a page with no focused form control.
  • The timed test starts on your first press, not on a separate Start button. That removes the dead time of clicking Start and waiting for a "go" signal, which would otherwise be extra reaction-time noise baked into every result.
  • The countdown and the final cut-off are handled by two independent timers — a setInterval that only repaints the "time left" display, and a single setTimeout fired at the exact duration that stops accepting presses. The display can lag by up to its own refresh interval; the actual cut-off point does not.
  • Presses per second is total presses ÷ the preset duration, not divided by however many milliseconds actually elapsed — the preset is exact, so there's nothing to gain from measuring wall-clock time to sub-millisecond precision for the denominator.

Best scores and local storage

Finishing a timed run compares your total against whatever is already saved for that exact duration in your browser's local storage, and overwrites it only if you beat it. The data lives under a single key, scoped to this site's origin, entirely on your device — there is no account system to log into and no server this could be sent to even if the tool wanted to send it. Clearing your browser's site data for this domain, using a different browser, or switching devices all reset it, because there is nothing anywhere else to fall back on.

Scope and honesty about limits

This tool reports exactly what the browser's keyboard events told it happened. It cannot see the mechanical switch underneath your keycap, it cannot know whether a background application intercepted a keystroke before the browser saw it, and it has no independent, verified figure for what an "average" presses-per-second score looks like across the population — so it doesn't claim one. As a way to sanity-check a possibly sticky or double-firing key it is a genuinely useful first pass, precisely because it counts real discrete presses instead of raw autorepeat; it is not a substitute for a dedicated keyboard-testing utility or opening the switch up if you need certainty.

If you find a case where the count on screen doesn't match what you believe you pressed — outside of the deliberate key-repeat filtering explained above — that's worth reporting; see contact.

How the site is built

  • Static HTML, one small stylesheet, two small scripts. No framework, no build step, no bundler.
  • Nothing here needs the network. No CDN framework, no web font, no remote image — the favicon is an inline SVG data URI. Once the page has loaded it keeps working offline.
  • System font stack. Your operating system's own UI font, so nothing has to download and nothing shifts as the page loads.
  • Dark mode follows your system setting via prefers-color-scheme, and any motion this page adds is disabled under prefers-reduced-motion.