View on GitHub


Turn your keyboard into a typewriter! 📇

Turn your keyboard into a typewriter! 📇

GitHub Release Crate Release Coverage
Continuous Integration Continuous Deployment Documentation

daktilo (“typewriter” in Turkish, pronounced “duck-til-oh”, derived from the Ancient Greek word δάκτυλος for “finger”) is a small command-line program that plays typewriter sounds every time you press a key. It also offers the flexibility to customize keypress sounds to your liking. You can use the built-in sound presets to create an enjoyable typing experience, whether you’re crafting emails or up to some prank on your boss.

✨ Inspiration: “Taking notes in class with my typewriter”

Now you can recreate this moment without the actual need for a physical typewriter!

Table of Contents - [Getting Started](#getting-started) - [Supported Platforms](#supported-platforms) - [Installation](#installation) - [Cargo](#cargo) - [Arch Linux](#arch-linux) - [Alpine Linux](#alpine-linux) - [MacPorts](#macports) - [Binary releases](#binary-releases) - [Build from source](#build-from-source) - [Usage](#usage) - [Configuration](#configuration) - [Adding custom presets](#adding-custom-presets) - [Sound Variation](#sound-variation) - [Similar Projects](#similar-projects) - [MacOS permissions](#macos-permissions) - [Acknowledgements](#acknowledgements) - [Donations](#donations) - [Contributing](#contributing) - [License](#license) - [Copyright](#copyright)

Getting Started

Simply run daktilo for the classic typewriter effect.

There are also different presets available:

Preset Name Description
default the classic typewriter effect
basic an alternative and more basic typewriter effect
musicbox plays random notes like a music box
ducktilo quack quack 🦆
drumkit dum, tss, cha! 🥁
spark high voltage high current typing experience ⚡

To list the presets:

daktilo --list-presets

To use a preset:

daktilo --preset musicbox

You can also use multiple presets at the same time:

# orchestra
daktilo -p default -p musicbox -p drumkit

To use a different output device:

daktilo --device pipewire

Also, you can use --list-devices to list the available output devices.

To variate the sounds and have a more realistic typewriter experience:

daktilo --variate-tempo 0.9,0.4 --variate-volume 0.1,0.5
Spoiler warning There are easter eggs. If that is something you do not like you can disable them either via the config file option `no_surprises = true` or using the command-line flag: ```sh daktilo --no-surprises ```

Supported Platforms


Packaging status


daktilo can be installed from using cargo if Rust is installed.

cargo install daktilo

The minimum supported Rust version is 1.70.0.

On Linux, the following packages should be installed:

Arch Linux

daktilo can be installed from the official repositories using pacman:

pacman -S daktilo

Alpine Linux

daktilo is available for Alpine Edge. It can be installed via apk after enabling the testing repository.

apk add daktilo


On macOS, daktilo can be installed via MacPorts:

sudo port install daktilo

More info here.

Binary releases

See the available binaries for different targets from the releases page.

Build from source

  1. Clone the repository.
git clone && cd daktilo/
  1. Build.
CARGO_TARGET_DIR=target cargo build --release

Binary will be located at target/release/daktilo.


daktilo [OPTIONS]


-v, --verbose                                    Enables verbose logging [env: VERBOSE=]
-p, --preset [<PRESET>...]                       Sets the name of the sound preset to use [env: PRESET=]
-l, --list-presets                               Lists the available presets
    --list-devices                               Lists the available output devices
-d, --device <DEVICE>                            Sets the device for playback [env: DAKTILO_DEVICE=]
-c, --config <PATH>                              Sets the configuration file [env: DAKTILO_CONFIG=]
-i, --init                                       Writes the default configuration file
    --variate-volume <PERCENT_UP[,PERCENT_DOWN]> Variate volume +/- in percent [env: DAKTILO_VOLUME=]
    --variate-tempo <PERCENT_UP[,PERCENT_DOWN]>  Variate tempo +/- in percent [env: DAKTILO_TEMPO=]
-h, --help                                       Print help (see more with '--help')
-V, --version                                    Print version


daktilo can be configured with a configuration file using the TOML format.

The path of the configuration file can be specified via --config argument or DAKTILO_CONFIG environment variable.

It can also be placed in one of the following global locations:

<config_dir> depends on the platform as shown in the following table:

Platform Value Example
Linux $XDG_CONFIG_HOME or $HOME/.config /home/orhun/.config
macOS $HOME/Library/Application Support /Users/Orhun/Library/Application Support
Windows {FOLDERID_RoamingAppData} C:\Users\Orhun\AppData\Roaming

See daktilo.toml for the default configuration options.

You can also create the default configuration file in the current directory with --init flag:

daktilo --init

Adding custom presets

The configuration file consists of an array of sound_preset entries.

To define an array in TOML, you can create different sections as follows:

name = "custom"
key_config = []

name = "another_custom"
key_config = []
disabled_keys = []
variation = { volume: [0.1, 0.1], tempo: [0.05, 0.05] }

As shown above, sound_preset consists of 2 entries:

Click for the list of available keys. `Alt`, `AltGr`, `Backspace`, `CapsLock`, `ControlLeft`, `ControlRight`, `Delete`, `DownArrow`, `End`, `Escape`, `F1`, `F10`, `F11`, `F12`, `F2`, `F3`, `F4`, `F5`, `F6`, `F7`, `F8`, `F9`, `Home`, `LeftArrow`, `MetaLeft`, `MetaRight`, `PageDown`, `PageUp`, `Return`, `RightArrow`, `ShiftLeft`, `ShiftRight`, `Space`, `Tab`, `UpArrow`, `PrintScreen`, `ScrollLock`, `Pause`, `NumLock`, `BackQuote`, `Num1`, `Num2`, `Num3`, `Num4`, `Num5`, `Num6`, `Num7`, `Num8`, `Num9`, `Num0`, `Minus`, `Equal`, `KeyQ`, `KeyW`, `KeyE`, `KeyR`, `KeyT`, `KeyY`, `KeyU`, `KeyI`, `KeyO`, `KeyP`, `LeftBracket`, `RightBracket`, `KeyA`, `KeyS`, `KeyD`, `KeyF`, `KeyG`, `KeyH`, `KeyJ`, `KeyK`, `KeyL`, `SemiColon`, `Quote`, `BackSlash`, `IntlBackslash`, `KeyZ`, `KeyX`, `KeyC`, `KeyV`, `KeyB`, `KeyN`, `KeyM`, `Comma`, `Dot`, `Slash`, `Insert`, `KpReturn`, `KpMinus`, `KpPlus`, `KpMultiply`, `KpDivide`, `Kp0`, `Kp1`, `Kp2`, `Kp3`, `Kp4`, `Kp5`, `Kp6`, `Kp7`, `Kp8`, `Kp9`, `KpDelete`, `Function`, `Unknown`

As an example, here is how you can configure key_config:

key_config = [
  { event = "press", keys = "Return", files = [{ path = "ding.mp3", volume = 1.0 }] },

If you have defined multiple files for a key event, you can also specify a strategy for how to play them:

key_config = [
  { event = "press", keys = ".*", files = [{ path = "1.mp3" }, { path = "2.mp3" }], strategy = "random" },

Currently supported strategies are:

Here is how you can combine everything together:

# Custom sound preset named "custom"
name = "custom"

# Key configurations for various events
key_config = [
  # When a key starting with "Key" is pressed, play 1.mp3, 2.mp3, and 3.mp3 sequentially
  { event = "press", keys = "Key*", files = [
    { path = "1.mp3" },
    { path = "2.mp3" },
    { path = "3.mp3" },
  ], strategy = "sequential" },

  # When a key starting with "Key" is released, play 4.mp3
  { event = "release", keys = "Key*", files = [
    { path = "4.mp3" },
  ] },

  # When a key starting with "Num" is pressed, play num.mp3 at a very high volume (10.0)
  { event = "press", keys = "Num*", files = [
    { path = "num.mp3", volume = 10.0 },
  ] },

  # When any key is pressed, play a random sound from cat.mp3, dog.mp3, or bird.mp3
  { event = "press", keys = ".*", files = [
    { path = "cat.mp3" },
    { path = "dog.mp3" },
    { path = "bird.mp3" },
  ], strategy = "random", variation = { volume: [0.1, 0.1], tempo: [0.05, 0.05] } },

# Disabled keys that won't trigger any sound events
disabled_keys = ["CapsLock", "NumLock"]

Sound Variation

To make the keyboard sounds more varied it is possible to variate both volume and playback speed (the later also varies the pitch).

Values are in percent, where the first value determines the maximum increase and the second the maximum decrease. The actual value is determined randomly on each keypress.

Similar Projects

MacOS permissions

On MacOS, you need to give some permissions to the terminal where you run daktilo.

The first time you run daktilo, you will probably see this popup:


If you see it, click on “Open System Settings”, otherwise open “System Settings” manually and go to “Privacy and Security”. From here, enable “Input Monitoring” for your terminal application:



Huge thanks to H. Arda Güler for giving me the idea for this project, sharing the inspiration behind it and implementing the first iteration in Python.

Kudos! 👾


Support me on GitHub Sponsors Support me on Patreon Support me on Patreon

If you find daktilo and/or other projects on my GitHub useful, consider supporting me on GitHub Sponsors or becoming a patron!


See our Contribution Guide and please follow the Code of Conduct in all your interactions with the project.

Also, see how you can add new presets here.


License: MIT License: Apache 2.0

Licensed under either of Apache License Version 2.0 or The MIT License at your option.

🦀 ノ( º _ º ノ) - respect crables!

Copyright © 2023-2024, Orhun Parmaksız