Install
# One-liner installer
bash <(curl https://raw.githubusercontent.com/atuinsh/atuin/main/install.sh)
# Or via package manager
sudo apt install atuin
brew install atuin
sudo pacman -S atuin
# Or via mise (see /tutorials/mise-polyglot-runtime-versions.html)
mise use -g atuin@latest
atuin --version
Hook into your shell
# bash — install bash-preexec first (atuin needs it)
curl https://raw.githubusercontent.com/rcaloras/bash-preexec/master/bash-preexec.sh \
-o ~/.bash-preexec.sh
echo '[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh' >> ~/.bashrc
echo 'eval "$(atuin init bash)"' >> ~/.bashrc
# zsh
echo 'eval "$(atuin init zsh)"' >> ~/.zshrc
# fish (see /tutorials/starship-fish-shell-setup.html)
echo 'atuin init fish | source' >> ~/.config/fish/config.fish
# nushell
mkdir -p ~/.config/atuin
atuin init nu > ~/.config/atuin/init.nu
echo 'source ~/.config/atuin/init.nu' >> ~/.config/nushell/config.nu
Reopen the shell. Type echo hello, then hit Ctrl-R: the Atuin TUI appears.
The Ctrl-R interface
By default, Atuin overrides Ctrl-R. You see a list of recent commands; type to fuzzy-filter; arrow-keys to navigate; Enter to select. Per-entry metadata visible: directory + host + exit-code + duration.
Useful keybindings inside the search:
- Ctrl-R — cycle between filter scopes: global, host, session, directory.
- Ctrl-S — cycle between sort modes (recent, frequent).
- Tab — complete to current input.
- Esc / Ctrl-C — cancel.
By default Atuin shows only the current host's history; Ctrl-R again to expand to "global" (every host you've synced).
Search from anywhere
# Search history from any prompt without entering interactive mode
atuin search "git push"
# Limit by directory
atuin search --cwd ~/projects/myapp "cargo"
# By exit code (find recent failures)
atuin search --exit 1 --before 1h "deploy"
# By host
atuin search --host laptop-01 "ssh"
Sync via Atuin's hosted service
# Register
atuin register --username amir --email amir@example.com
# Sync
atuin sync
# Subsequent shells auto-sync in the background
The default sync target is api.atuin.sh (Atuin's hosted free service). End-to-end encrypted — the server stores ciphertext only; the key is on each of your devices. To set up on a new machine: atuin login, paste the key (printed during registration; store it in a password manager).
Self-host the sync server
For full control, run the Atuin server on your own infrastructure:
# docker-compose.yml
services:
atuin:
image: ghcr.io/atuinsh/atuin:latest
container_name: atuin
restart: unless-stopped
ports:
- "127.0.0.1:8888:8888"
environment:
ATUIN_HOST: "0.0.0.0"
ATUIN_PORT: 8888
ATUIN_OPEN_REGISTRATION: "true"
ATUIN_DB_URI: postgres://atuin:${DB_PW}@postgres/atuin
command: atuin server start
depends_on: [ postgres ]
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: atuin
POSTGRES_PASSWORD: ${DB_PW}
POSTGRES_DB: atuin
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Reverse-proxy to atuin.example.com over HTTPS. On each device:
# Set the sync URL
atuin set sync.address https://atuin.example.com
atuin register ... # or login on a known account
Disable open registration after creating your accounts: ATUIN_OPEN_REGISTRATION: "false".
Filtering noise
By default Atuin records every command, which includes mistyped passwords, secrets piped via stdin, etc. Filter at record time:
# ~/.config/atuin/config.toml
[stats]
ignored_commands = ["password", "echo $TOKEN"]
# Ignore commands matching a regex
history_filter = [
"^secret_command",
"ssh.*--password",
]
# Ignore commands by working directory
cwd_filter = [
"~/.secrets",
]
Stats
atuin stats # daily / weekly summaries
atuin stats day # commands run today
atuin stats week
atuin stats all # entire history
# Top commands across all-time
atuin search --cmd-only --count 20 ""
Import existing history
# First-time setup: import from your existing shell history
atuin import auto
# Or specifically
atuin import bash
atuin import zsh
atuin import fish
Your existing thousands of commands become searchable; subsequent commands accumulate alongside them.
Why this beats the default Ctrl-R
- Real fuzzy search across all of history, not just substring match against the last N lines.
- Per-directory context: "what did I run last time I was in this repo?"
- Per-host context: "where did I run this?" The shell that has it isn't always the one you're sitting at.
- Exit-code awareness: filter to failures only, or successes only.
- Multi-machine: yesterday's commands from the office laptop are available from the home one.
- The encrypted sync isolates the privacy issue with cloud history features — it's E2E; the server can't read it.
What it doesn't do
- It's not a shell — it integrates with your existing shell (bash, zsh, fish, nushell).
- It doesn't replace your prompt — pair with starship (see that tutorial).
- It can't undo commands — just search history; the actual filesystem mutations are not reversible by Atuin.