Clack is an extremely realistic typing simulator that translates static text or standard input into a dynamic, human-like keystroke stream.
Clack is heavily inspired by and credits its core idea to htype (https://github.com/lord-of-the-strings/htype), originally created by Aadity Setu.
If you are generating screencasts, terminal recordings, or automated UI demonstrations, regular typing automation tools like xdotool or basic sleep scripts look robotic and fake. Clack utilizes probabilistic models to simulate how a real human types, complete with motor-control panics, realistic typing speeds, error rates, and layout-aware key travel distances.
CLACKDemo.mp4
Clack 2.0 introduces a brand new, fully-featured GTK4 Graphical Interface for Linux! You no longer need to rely purely on the command line to configure your virtual typist.
- Live Tuning: Adjust WPM, Error Rates, and Correction probability via sliders and instantly see the results.
- Typing Presets: Switch between pre-configured typing styles like Casual, Hunt & Peck, Proficient, and Fast on the fly.
- No Leftover Mistakes: A highly-requested toggle that ensures your final text is 100% correct, while still authentically simulating the process of making and fixing mistakes as it types.
- Global Shortcuts (WIP): Pause, resume, or trigger speed-boosts globally using keyboard shortcuts without needing to focus the application window.
- Cross-Window Compatibility: Type directly into any target application window using secure
/dev/uinputinjection.
Clack doesn't just add a random delay between keypresses. It simulates an entire virtual typist sitting at a keyboard. It employs several advanced mechanics to achieve this:
- Bimodal Timing Distributions: Human typing has two distinct rhythms. We type adjacent letters in a word quickly, but pause longer at word boundaries, punctuation, and capital letters. Clack models this using Gaussian distributions.
- Euclidean Key Distances: Clack understands the physical layout of your keyboard (QWERTY, Dvorak, Colemak, AZERTY). Moving your finger from 'a' to 'z' is faster than moving from 'a' to 'p'. Clack dynamically calculates the physical travel distance between consecutive keys to adjust the inter-key timing.
- Probabilistic Errors & Corrections: Humans make mistakes! Clack can simulate typos (hitting an adjacent key), transpositions (swapping two letters), and omissions. It then realistically realizes the mistake, pauses, backspaces, and re-types the correct characters.
- Panic Events: Sometimes, a typist's brain glitches. Clack simulates rare "Panic Events" where the virtual typist accidentally holds down a key for too long (a stuck-key burst) or gets confused and re-types the prefix of the current word before backspacing to fix it.
- Code-Aware Typing Mode: Typing source code requires more cognitive load than typing prose. When enabled, Clack tracks the depth of nested brackets
{} [] ()and slows down the typing speed for deeper scopes. It also detects complex identifiers (snake_case,camelCase) and types them more carefully to reflect real programming behavior.
Clack is built in Rust for maximum performance, with a modern GTK4 Python frontend.
If you are using a Debian-based Linux distribution (Ubuntu, Mint, Pop!_OS, etc.), the easiest way to install Clack is using the .deb package. This installs the clack CLI tool and the clack-gui Desktop Application.
- Download the
clack_v2_amd64.debfile from the Releases page. - Install the package via terminal:
sudo dpkg -i clack_v2_amd64.deb sudo apt-get install -f # To resolve any missing dependencies automatically - Open "Clack" from your desktop application launcher, or run
clack-guiin the terminal!
If you are using Arch, Fedora, Alpine, or prefer portable executables, use the .tar.gz archive.
- Download
clack-2.0.0-x86_64-linux-gnu.tar.gz. - Extract the archive and ensure you have
ydotoolandpython3-giinstalled on your system. - Run the CLI directly or execute the
guipython module.
If you have Rust and Cargo installed, you can compile Clack natively:
git clone https://github.com/ThisWasAryan/clack.git
cd clack
cargo build --releaseTo run the GUI from source:
sudo apt install ydotool python3-gi python3-gi-cairo gir1.2-gtk-4.0
# Start the ydotool daemon with open socket permissions so your user can access it
sudo ydotoold --socket-perm 0666 &
python3 -m guiIf you prefer the command line, Clack still supports its powerful CLI backend. It accepts input from standard input (stdin) and outputs the simulated keystroke timing stream to standard output (stdout).
Pipe a string into clack:
echo "Hello, world! I am a simulated human." | clackSimulate a very fast, erratic typist who makes lots of mistakes:
echo "I'm typing really fast but making so many typos!" | clack --wpm 140 --jitter 0.3 --error-rate 0.1Simulate a slow, careful programmer typing Dvorak:
cat main.rs | clack --wpm 45 --layout dvorak --code-mode --error-rate 0.01| Flag | Type | Default | Description |
|---|---|---|---|
--wpm |
float | 60.0 |
Target average words per minute |
--jitter |
float | 0.15 |
IKI (Inter-Key Interval) jitter coefficient (0.0 = none, 1.0 = extreme) |
--error-rate |
float | 0.04 |
Base probability of generating an error per character (0.0β1.0) |
--correction-rate |
float | 0.85 |
Fraction of generated errors that get corrected |
--no-errors |
flag | off | Disable all error generation |
--seed |
int | (random) | RNG seed for deterministic output. When set, behavior is fully reproducible |
--session-length |
int | 500 |
Expected total character count; used to compute warmup/fatigue curves |
--no-fatigue |
flag | off | Disable warmup and fatigue session modelling |
--max-pause |
int | 5000 |
Maximum any single pause may be in milliseconds |
--thinking-pause-prob |
float | 0.015 |
Probability of a stochastic thinking pause between any two words |
--state-output |
flag | off | Emit behavioral state transitions to stderr |
--code-mode |
flag | off | Slows down for nested brackets and complex identifiers |
--layout |
string | qwerty |
Target keyboard layout (qwerty, dvorak, colemak, azerty) |
--version |
flag | β | Print version string and exit |
The default parameters and modeling techniques in Clack are derived from extensive academic research on human keystroke dynamics. Rather than relying on simple sleep delays, every value traces its origins back to research:
The IKI distribution is right-skewed, not Gaussian. We model the delay between keypresses as a log-normal distribution, ensuring extreme realism. Fast typists average ~120 ms between keys, while slower typists average ~480 ms, with an absolute physical minimum (hard floor) of 60 ms.
Errors in fast typing naturally occur at a rate of 4%β8%, broken down by precise human fallibility ratios:
- Substitution (adjacent key): ~39%
- Insertion (extra character): ~33%
- Omission (missing character): ~21%
- Transposition (swap two adjacent): ~5% (76% occurring across hands)
- Doubling (letter doubled): ~2%
Clack computes the physical Euclidean distance between keys on the selected layout (e.g., QWERTY, Dvorak). Transitioning from A to Z is significantly faster than A to P. Distances map to specific IKI multipliers. Hand-alternating bigrams (e.g., left hand E β right hand R) are mathematically enforced to be up to 18% faster than same-hand sequences.
Pauses are separated into specific cognitive events:
- Word Boundary Pauses: Log-normal pause at the end of a word (~80 ms mean).
- Sentence Boundary Pauses: End-of-thought pauses after
.?!(~600 ms mean). - Line-start Hesitation: Brief re-orientation before starting a new line.
- Session Fatigue: Fatigue models gradual IKI multiplier increases and spikes in errors. Lapses ("mental blocks") with very long IKIs begin appearing late in typing sessions.
- Dhakal et al., "Observations on Typing from 136 Million Keystrokes", CHI 2018. URL: https://userinterfaces.aalto.fi/136Mkeystrokes/
- Clarkson (2005) mini-QWERTY study; CHI 2025 "Simulating Errors in Touchscreen Typing" (arXiv 2502.03560).
- "On the shape of timings distributions in free-text keystroke dynamics profiles", PMC8606350.
- "Age Modulates the Effects of Mental Fatigue on Typewriting", Frontiers in Psychology 2018 (PMC6049040).
- "Dynamics in typewriting performance reflect mental fatigue during real-life office work", PLOS ONE 2020 (PMC7537853).
Clack ensures O(1) per-character processing overhead, meaning it can generate timing events infinitely without memory scaling issues. It is strictly deterministic when given a seed.
stdin
β
βΌ
[Reader]
β character stream
βΌ
[Tokenizer] β splits into: regular chars, word boundaries, sentence boundaries, newlines
β
βΌ
[State Machine] β current state: FOCUSED / FLOW / THINKING / DISTRACTED / FATIGUED
β modifies: speed multiplier, pause probability, error probability
βΌ
[Timing Engine] β computes per-character delay using:
β base IKI, jitter, momentum, keyboard model, word/sentence pauses
βΌ
[Error Engine] β stochastically injects errors before emission
β
βΌ
[Correction Engine] β decides: immediate correct, delayed correct, uncorrected
β
βΌ
[Output] β sleep(delay), write(char) to stdout
Clack implements multiple dynamic correction strategies.
- Immediate Correction (~70%): A typo is immediately recognized. A realistic backspace delay sequence is emitted (
\x08 \x20 \x08) followed by the correct characters. - Delayed Correction (~30%): The typist makes a mistake but continues typing 3-12 characters before "noticing" the error, pausing in confusion, erasing everything up to the mistake, and re-typing the rest of the word correctly.
The repository is highly modularized to separate core simulation logic from platform-dependent I/O operations and graphical user interfaces.
clack/
βββ Cargo.toml # Workspace manifest
βββ clack-core/ # Highly-optimized Rust Library β 0% I/O, 100% Simulation
β βββ src/
β βββ lib.rs # Public API: ClackEngine, ClackConfig, ClackEvent
β βββ timing.rs # Log-normal sampling, base IKI logic, bursts
β βββ state.rs # Behavioral state transitions and matrices
β βββ keyboard.rs # Layout grids, Euclidean distance maps, hand-alternation rules
β βββ error.rs # Probabilistic error generation (sub, add, omit, trans, double)
β βββ pause.rs # Sentence, word, and stochastic thinking pauses
β βββ session.rs # Session progress, warmup curve, fatigue curve, lapses
β βββ language.rs # Common word lists, difficult word heuristics
β βββ correction.rs # Backspacing, immediate vs delayed correction state machines
βββ clack-cli/ # Thin Rust CLI driver
β βββ src/main.rs # Stdin β Engine β Stdout stream plumbing (100% I/O)
βββ gui/ # GTK4 Python Frontend
βββ __main__.py # Entrypoint
βββ app.py # Main GTK Application loop and style contexts
βββ window.py # Main window layout, controllers, and components
βββ injector.py # Secure uinput daemon / ydotoold wrapper for external injection
βββ focus_watcher.py # System-wide window focus tracking
βββ clack_runner.py # Subprocess interaction tying the Rust CLI to the GUI
βββ settings.py # Advanced settings panel UI
βββ presets.py # Tuned presets (Hunt&Peck, Casual, Fast) and modifiers