A terminal typing practice app for developers. Practice typing prose, code, symbols, numbers, and vim/tmux key sequences — all from the terminal. Import your own documents for personalized practice.
┌──────────────────────────────────────────────┐
│ c a t y p e │
│ Hello, jixian │
│ │
│ ▸ Mode ◂ Sentence ▸ │
│ Category [email] │
│ Order [Sequential] │
│ Scope [Whole category] │
│ Length [60s] │
│ │
│ j/k navigate h/l change │
│ Enter start p profile d docs │
│ q quit │
└──────────────────────────────────────────────┘
Four practice modes
- Word — individual words extracted from documents, optionally weighted by error history
- Phrase — multi-word chunks from documents
- Sentence — full sentences from documents
- Document — type an entire document sequentially
Category-based corpus — practice material is organized by category (e.g., email, academic, prompt). Built-in categories ship with the app; import your own documents to create custom categories.
Document import — import your own files for practice
- Supports txt, html, pdf, and docx formats
- Browse documents by category, configure session options, start typing
- Error-weighted document selection targets your weakest characters
- Infinite mode keeps generating prompts until you stop
Configurable sessions
- Timed (60s, 120s), fixed word count (60, 120), whole document, or infinite
- Custom passing thresholds (accuracy and WPM, adjustable in profile)
- Every keystroke counts — backspace corrections are penalized
Real-time feedback
- Character-level green/red coloring as you type
- Live WPM and accuracy display
Session tracking
- All sessions persisted to a local SQLite database
- Per-prompt error logs (which characters were wrong)
- Per-character accuracy stats across all sessions
- Daily practice time tracking
- Statistics view with session history, practice time chart, weakest keys
User profile
- Named profile with rename and reset
- Custom accuracy and WPM thresholds
- Daily practice goal
- Keyboard heatmap showing per-key accuracy and frequency
Requires Rust toolchain.
git clone <repo-url> && cd catype
cargo build --release
# Binary at target/release/catype# Launch with defaults (Sentence mode, 60s timed)
catype
# Override via CLI flags
catype --mode sentence --time 30
catype --mode word --count 20
catype --min-accuracy 95 --min-wpm 40# Import files for typing practice
catype import --file essay.txt --category academic
catype import --file report.html --category work --title "Q4 Report"
catype import --file paper.pdf --category research
catype import --file notes.docx --category personal
# List imported documents
catype list
catype list --category academic
# Delete a document
catype delete 3
# Sync built-in corpus from index.csv into the database
catype sync
catype sync --dir src/corpus
# Clear data
catype clear --documents # Remove all imported documents
catype clear --profile # Clear sessions, stats, practice historyPDF imports include spell checking against the system dictionary — sentences with unrecognized words are flagged for review.
| Screen | Key | Action |
|---|---|---|
| Menu | j/k, arrows | Navigate options |
| Menu | h/l, arrows | Cycle option values |
| Menu | Enter | Start session |
| Menu | p | Profile |
| Menu | s | Statistics |
| Menu | d | Document browser |
| Menu | q | Quit |
| Typing | (type normally) | Match the target text |
| Typing | Backspace | Delete last character |
| Typing | Esc | End session early |
| Results | r | Retry with same settings |
| Results | m | Back to menu |
| Doc Browser | j/k | Navigate within panel |
| Doc Browser | Tab | Switch between panels |
| Doc Browser | Enter | Select category/document |
| Doc Browser | Esc | Back to menu |
| Doc Viewer | j/k | Scroll through document |
| Doc Viewer | Esc | Back to browser |
| Profile | j/k | Navigate options |
| Profile | h/l | Adjust thresholds |
| Profile | Esc | Back to menu |
| Stats | j/k | Navigate sessions |
| Stats | Tab | Switch tabs |
| Stats | Enter | View session detail |
| Stats | Esc | Back to menu |
| Session Detail | Esc | Back to stats |
The menu fields change based on the selected mode:
- Mode — Word, Phrase, Sentence, Document
- Category — cycles through available categories (built-in + imported)
- Order — Sequential or Random (hidden in Document mode)
- Scope — Random document or Whole category (hidden in Document mode)
- Focus — Uniform or Weak chars (only shown in Word mode)
- Length — 60s, 120s, 60w, 120w, Whole document, Infinite
Optional config file at ~/.config/catype/config.toml:
mode = "sentence"
[session]
kind = { type = "Timed", value = 60 }
[thresholds]
accuracy = 98.0
wpm = 35.0CLI flags override the config file, which overrides built-in defaults. Custom thresholds set in the profile menu are stored in the database and take precedence over config file defaults.
- WPM:
(correct_chars / 5) / elapsed_minutes. Timer starts on the first keystroke. - Accuracy:
correct_keystrokes / total_keystrokes * 100. Every key press counts, including ones corrected with backspace. - Pass/Fail: Both accuracy and WPM must meet their thresholds independently.
Plain text files organized by category in src/corpus/, indexed by src/corpus/index.csv:
src/corpus/
├── index.csv # Maps categories to text files
├── academic/
│ ├── ensemble_fire_abstract.txt
│ ├── ensemble_fire_introduction.txt
│ ├── uncertainty_tube_abstract.txt
│ └── uncertainty_tube_method.txt
├── email/
│ ├── email1.txt
│ ├── email2.txt
│ ├── email3.txt
│ ├── email4.txt
│ └── email5.txt
└── prompt/
├── prompt1.txt
├── prompt2.txt
├── prompt3.txt
└── skills1.txt
To add entries, create a text file in the appropriate category subdirectory, add a row to index.csv, and run catype sync.
Import your own files for practice:
catype import --file myfile.txt --category mycategorySupported formats: .txt, .html/.htm, .pdf, .docx
Documents are stored in the SQLite database as sequences of sentences. The document browser (press d from the main menu) lets you browse by category and view individual documents.
All data is stored in ~/.config/catype/catype.db (SQLite). The database is created automatically on first run. Use the profile screen (press p) to reset session data, or catype delete <id> to remove individual documents, or catype clear to bulk-clear data.