keyrave
v0.1.2
Published
Your keyboard, throwing a rave. Terminal typing visualizer with zero dependencies.
Maintainers
Readme
KEYRAVE
Your keyboard, throwing a rave. A zero-dependency terminal typing visualizer.
Not a typing speed meter — a music visualizer where your keystrokes are the instrument.
Install / Run
npm install # nothing to actually install — zero runtime deps
npm link # optional: makes `keyrave` available globally
keyrave # or: node bin/keyrave.jsRequires an interactive terminal (TTY) — it reads raw keypresses, so it won't do anything piped or in a non-interactive shell.
Quit with Esc or Ctrl+C — the terminal is restored to exactly how it
was (alternate screen buffer, cursor visibility, raw mode all cleaned up).
What each key does
| Key | Effect |
|---|---|
| any letter/number/symbol | splash centered on a column derived from the character, radius/brightness scaled by intensity |
| Enter | bass drop — full-width flash, screen shake, big particle burst |
| Backspace | purple reverse ripple from the last hit point outward |
| Space | wide horizontal wave across the whole width |
| Tab | rainbow sweep |
| holding Shift (typing a capital) | white flash |
| Ctrl+E | export a session snapshot (ASCII + SVG + animated SVG) |
| Esc / Ctrl+C | quit cleanly |
Configuration
Every tuning knob lives in a single JSON file. KEYRAVE looks for it in this order:
--config <path>on the command line./.keyraverc.json,./.keyraverc, or./keyrave.jsonin the current directory~/.config/keyrave/config.jsonor~/.keyraverc.json
A missing file means defaults; a malformed file prints a warning and keeps going.
// keyrave.json
{
"rows": 16, // "bars per column" — bar height resolution
"fps": 45,
"colors": {
"saturation": 0.85,
"lightness": 0.55,
"driftSpeed": 12, // ambient hue drift, degrees/sec
"baseHue": 270, // calm hue at intensity 0
"intensitySweep": 245, // hue sweep as intensity goes 0 -> 1
"hueStepPerBar": 35 // vertical color gradient per bar unit
},
"physics": {
"spring": 90,
"damping": 9,
"gravity": 2.4,
"targetDecay": 0.9, // decay rate — splash fade speed
"peakHoldSeconds": 0.5,
"peakFallRate": 0.7
},
"intensity": {
"baselineStart": 45,
"baselineBlend": 0.995, // how fast it adapts to your normal speed
"smoothing": 0.85,
"idleDecay": 0.995
},
"combo": { "pauseThresholdMs": 1500 },
"particles": { "max": 400, "gravity": 3 },
"rhythm": {
"sampleSize": 12,
"maxIntervalMs": 2000,
"tolerance": 0.28,
"pulseAmplitude": 0.12 // beat sensitivity — BPM pulse strength
},
"export": {
"dir": ".",
"prefix": "keyrave",
"ascii": true,
"svg": true,
"animated": true,
"historySeconds": 3
}
}Only the keys you set are overridden — everything else keeps its default.
Exporting snapshots
Press Ctrl+E mid-session and KEYRAVE writes three files to the export dir:
keyrave-snapshot-<timestamp>.txt— ASCII art of the current framekeyrave-<timestamp>.svg— vector snapshot (bars, peaks, particles)keyrave-animated-<timestamp>.svg— animated replay of the last few seconds
Use export.dir, export.prefix, and the ascii/svg/animated flags in the
config to control what gets written and where.
Why "adaptive" intensity instead of fixed thresholds
IntensityEngine keeps a slow-moving average of your own recent WPM as a
baseline, then measures how far above/below that you currently are. A 45
WPM typist and a 150 WPM typist can both reach a "maxed out" rave — it's
about relative effort, not an absolute number.
