Skip to main content

ttytype

CI Python 3.14 License: MIT

A keyboard-first terminal typing test built with Textual. It supports word-count, timed, public-domain quote, and private custom-text tests without accounts, telemetry, or network access.

ttytype Home screen

Features

  • Live raw and net WPM, accuracy, time, progress, and error feedback.
  • Word, timed, quote, and custom-text modes.
  • Dark and light variants with redundant non-color character-state cues.
  • Responsive layouts and a guarded small-terminal fallback.
  • Optional local SQLite history, recent results, and personal bests.
  • Linux, macOS, and Windows support through Textual and Platformdirs.

Installation

ttytype requires Python 3.14 or newer. PyPI publication is deferred for the initial release; install the tagged source with either tool:

uv tool install "ttytype @ git+https://github.com/jakeryderv/ttytype.git@v0.1.0"
# or
pipx install "ttytype @ git+https://github.com/jakeryderv/ttytype.git@v0.1.0"

Run the installed command:

ttytype
# Equivalent module entry point:
python -m ttytype

For a source checkout:

git clone https://github.com/jakeryderv/ttytype.git
cd ttytype
uv sync --locked
uv run ttytype

Controls

Context Key Action
Everywhere Ctrl+Q Quit
Everywhere Ctrl+T Toggle light/dark theme
Home Tab / Shift+Tab Move focus
Home Enter Open a selection or press a button
Typing Printable keys Type the target text
Typing Backspace Remove the final typed character
Typing Tab Retry the exact target
Typing Escape Return Home
Results R Retry the exact target
Results N Generate new text with the same configuration
Results H Return Home
Results Q Quit

ttytype active typing screen

Test modes

  • Words: 10, 25, 50, or 100 lowercase common words.
  • Timed: 15, 30, 60, or 120 seconds. Timing starts on the first printable character and ends from the monotonic clock; input at the exact deadline is rejected. More local words are generated before the visible buffer runs out.
  • Quote: short, medium, or long public-domain excerpts with capitalization, punctuation, author, and work attribution preserved.
  • Custom text: paste or enter plain text in the TUI. Multiline and repeated whitespace are normalized to spaces for a single terminal-friendly target. File loading is deferred; no custom text is persisted.

Scoring

  • Raw WPM: all printable character keystrokes divided into standard five-character words per minute.
  • Net WPM: currently correct target positions divided into five-character words per minute.
  • Accuracy: correct printable keystrokes divided by all printable keystrokes. Backspace is excluded, so a corrected mistake still affects accuracy.
  • Errors: incorrect character attempts remain in the total; corrected and currently uncorrected errors are reported separately.

Timing starts on the first printable character using a monotonic nanosecond clock and remains independent from the UI refresh rate.

Local history and privacy

ttytype is local-only:

  • There are no accounts, network requests, synchronization, telemetry, or analytics.
  • Completed sessions are saved only when Save completed tests locally is enabled.
  • Home can disable future history and permanently clear existing history after confirmation.
  • History stores score metadata and chart samples. It does not store target text, typed text, custom text, or individual keystrokes.
  • WPM chart samples use compact JSON arrays with the shape [elapsed_ms, raw_wpm, net_wpm, accuracy].

The SQLite database is created lazily when the application first accesses local preferences or history.

Storage locations

Paths are selected with platformdirs.user_data_path("ttytype"):

Platform Default database path
Linux $XDG_DATA_HOME/ttytype/ttytype.sqlite3, normally ~/.local/share/ttytype/ttytype.sqlite3
macOS ~/Library/Application Support/ttytype/ttytype.sqlite3
Windows %LOCALAPPDATA%\ttytype\ttytype\ttytype.sqlite3

Environment and operating-system configuration may change these locations. Mutable preferences and history share this database. ttytype does not currently write a TOML configuration file. A future configuration directory is reserved through platformdirs.user_config_path("ttytype").

Configuration and CLI

Defaults are 25 words, local history enabled, and the dark theme. Home edits mode-specific word count, duration, quote length, and history behavior. Ctrl+T changes the stored theme preference. Custom text itself is never persisted.

Configuration precedence, from lowest to highest, is:

  1. application defaults;
  2. stored SQLite preferences;
  3. explicit command-line overrides;
  4. choices made in the running TUI, which are persisted for later launches.
ttytype [--words COUNT] [--history | --no-history] [--theme dark|light]

--words opens Home in word mode at the requested count. History and theme options override stored preferences for the running application.

Supported systems and terminals

CI runs the full Python 3.14 quality suite on current Ubuntu, macOS, and Windows GitHub-hosted runners. ttytype expects an interactive terminal with Unicode and ANSI color support. True color improves appearance but is not required because character states also use bold, reverse, underline, and dim styles.

The typing view requires at least 50 columns by 12 rows. Larger terminals receive narrow, normal, or wide responsive layouts. Common modern terminals such as Windows Terminal, iTerm2, Terminal.app, GNOME Terminal, Konsole, and Kitty should work through Textual; terminal-specific rendering differences may remain.

Textual cutover

The original curses interface and its compatibility modules have been removed. These differences are intentional:

  • ttytype opens on Home rather than immediately starting a test;
  • Escape returns Home, while Ctrl+Q quits globally;
  • Tab retries the exact target and Results offers separate retry and new-text actions;
  • scoring uses event-based raw WPM, net WPM, accuracy, and corrected errors;
  • --words configures Home instead of bypassing it.

Development

Install the locked development environment:

uv sync --locked --all-extras --dev

Run the complete local quality gate:

uv run ruff check .
uv run ruff format --check .
uv run mypy src tests
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 uv run pytest
uv build

GitHub Actions runs these checks on Linux, macOS, and Windows and uploads wheel and source-distribution artifacts. Version tags build separate release artifacts; PyPI publishing is intentionally not configured yet.

Project policy

Release notes are maintained in CHANGELOG.md. A separate contribution guide is deferred until the project receives external contribution workflow requirements. Standalone binaries are also deferred; the initial release is distributed as Python source and wheel artifacts.

License

Released under the MIT License.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ttytype-0.1.0.tar.gz (27.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ttytype-0.1.0-py3-none-any.whl (39.3 kB view details)

Uploaded Python 3

File details

Details for the file ttytype-0.1.0.tar.gz.

File metadata

  • Download URL: ttytype-0.1.0.tar.gz
  • Upload date:
  • Size: 27.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ttytype-0.1.0.tar.gz
Algorithm Hash digest
SHA256 416ad84743811ea72f808f83b4853a7be584f4c346dde6ff5ce98267ef657dd6
MD5 c070de0bddb19a3eb353f84a8bf57a60
BLAKE2b-256 70da77d324bf36a98fcc9226f70bf205b733763cb41e2f8075a23d091283e0d1

See more details on using hashes here.

Provenance

The following attestation bundles were made for ttytype-0.1.0.tar.gz:

Publisher: release.yml on jakeryderv/ttytype

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ttytype-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ttytype-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 39.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ttytype-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eab22af29c1f9d5ea3fac1e71c233e81555dfa1cc4a9baf5a027cddbb965fa1e
MD5 3b12e7058a02d0b702b4bf873e8f3604
BLAKE2b-256 96795f6a8320e99546b7816afe61d2aee46dea4a685efe11f587e27805c46bae

See more details on using hashes here.

Provenance

The following attestation bundles were made for ttytype-0.1.0-py3-none-any.whl:

Publisher: release.yml on jakeryderv/ttytype

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.1

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page