Skip to content
STACK IT FAST

Atuin

Curated OSSClassicShell History Sync2-5 people

Audited from github.com/atuinsh/atuin

Atuin replaces shell history with a local SQLite database that records context such as exit code, directory and duration, and offers end-to-end encrypted sync between machines through a self-hostable Rust server.

Language
Rust
Database
SQLite
Hosting
Docker
License
MIT
Running for
5 years
Team
2-5 people

Why this architecture

Atuin keeps history local in SQLite and encrypts it before sync, so the Axum sync server stays a thin store; a gRPC daemon and capability crates (CLI, server, AI, dotfiles) let each part evolve behind feature flags.

Tech stack by layer

13 technologies · audited Oct 2, 2026
Frontend & UI
  • RatatuiTerminal UI for the full-screen history search bound to ctrl-r and the up arrow, rendered with crossterm.
Backend & APIs
  • RustLanguage for the CLI, daemon, server and every crate in crates/ (edition 2024, Rust 1.95 minimum).
  • AxumHTTP framework of the atuin-server sync server, with tower-http middleware.
  • gRPCatuin-daemon serves a local gRPC API with tonic and prost; protobufs are compiled at build time with protox.
  • PASETOrusty_paseto and rusty_paserk handle key material, and crypto_secretbox encrypts history before it is synced.
Data & Persistence
  • SQLiteLocal history database on every machine, accessed through sqlx with the regexp extension.
  • PostgreSQLSync server database; atuin-server also builds sqlx drivers for SQLite and MySQL.
  • FjallEmbedded key-value store used by the daemon.
Infrastructure & Deploy
  • Dockercargo-chef multi-stage build of atuin-server on Debian slim, running as a non-root user with a /healthz check on port 8888.
  • KubernetesExample manifests for running the sync server: atuin.yaml, namespaces.yaml and secrets.yaml.
  • PrometheusServer metrics through the metrics crate and metrics-exporter-prometheus.
  • BuildkiteMain CI pipeline in .buildkite/pipeline.yml; GitHub Actions handle releases, Docker images, docs and Windows builds.
  • cargo-distdist-workspace.toml configures release artifacts and installers, including the optional self-update feature.
  • Nixflake.nix, default.nix and atuin.nix package Atuin for Nix; update-nix-deps.yml keeps hashes current.
Tooling, Testing & Ops
  • Model Context Protocolatuin-ai depends on rmcp, the Rust MCP SDK, alongside tree-sitter shell parsers for its AI features.
  • AGENTS.mdAgent instructions at the root, plus skills under .claude/skills and .atuin/skills.

Atuin architecture diagram

Open SVG
Atuin architecture diagramShell plugin → atuin CLI and TUI (record command); atuin CLI and TUI → atuin-daemon (gRPC); atuin CLI and TUI → Local history (read / write); atuin-daemon → Local history; atuin CLI and TUI → atuin-server (encrypted sync); atuin-server → Sync database (sqlx)CLIENTSSERVICESDATA & STORAGEShell pluginzsh · bash · fish · nuatuin CLI and TUIRust · ratatuiatuin-daemontonic gRPCatuin-serverRust · AxumLocal historySQLite · sqlxSync databasePostgreSQLrecord commandgRPCencrypted syncsqlxread / write
How the main components of Atuin connect, drawn from the audited repository.
Diagram as text
  • Shell plugin (zsh · bash · fish · nu) → atuin CLI and TUI (Rust · ratatui): record command
  • atuin CLI and TUI (Rust · ratatui) → atuin-daemon (tonic gRPC): gRPC
  • atuin CLI and TUI (Rust · ratatui) → Local history (SQLite · sqlx): read / write
  • atuin-daemon (tonic gRPC) → Local history (SQLite · sqlx)
  • atuin CLI and TUI (Rust · ratatui) → atuin-server (Rust · Axum): encrypted sync
  • atuin-server (Rust · Axum) → Sync database (PostgreSQL): sqlx

Key architectural decisions

5 decisions
  1. 01

    Local-first SQLite, optional encrypted sync

    The README says Atuin replaces shell history with a SQLite database and offers optional, fully encrypted sync through an Atuin server. atuin-client uses sqlx with SQLite, and atuin-common brings crypto_secretbox plus PASETO crates, so the server only ever stores ciphertext.

  2. 02

    Server is a small Axum app over sqlx with three databases

    crates/atuin-server builds the atuin-server binary on axum, tower-http and sqlx with postgres, sqlite and mysql features, and exports Prometheus metrics. Its integration tests start a real server and drive it with the client's API client, kept as a dev-dependency so the CLI stays free of server dependencies.

  3. 03

    A local daemon with a gRPC API

    crates/atuin-daemon runs in the background with tonic and prost (protobufs compiled by protox at build time), an embedded Fjall store and socket activation via listenfd on Linux, so shells talk to a long-lived process instead of opening the database on every command.

  4. 04

    Workspace split by capability

    crates/* separates atuin (the CLI), atuin-client, atuin-server, atuin-daemon, atuin-domain (shared API types with optional axum handlers), atuin-history, atuin-dotfiles, atuin-kv, atuin-scripts, atuin-pty-proxy and atuin-ai, and the atuin crate turns them on through features such as sync, daemon, ai and pty-proxy.

  5. 05

    AI features built on MCP

    crates/atuin-ai depends on rmcp, the Rust Model Context Protocol SDK, plus tree-sitter-bash and tree-sitter-fish, ratatui and an SSE client (eventsource-stream), and is part of the default feature set of the atuin binary.

How Atuin is built

How Atuin is structured

Atuin is a Cargo workspace (members = ["crates/*"], version 18 in Cargo.toml) with one crate per capability:

Crate Role
crates/atuin The atuin binary: shell integration, search UI, CLI commands, with features sync, daemon, ai, pty-proxy, clipboard
crates/atuin-client Local database, settings, sync client
crates/atuin-daemon Background daemon with a gRPC API
crates/atuin-server Sync server library and atuin-server binary
crates/atuin-domain API and domain types shared by client, daemon and server, with optional axum handlers
crates/atuin-common Crypto, database helpers, shared utilities
crates/atuin-history, atuin-dotfiles, atuin-kv, atuin-scripts History ranking, synced dotfiles and aliases, key-value store, saved scripts
crates/atuin-pty-proxy PTY proxy for capturing terminal output on Unix
crates/atuin-ai AI features built on MCP and tree-sitter

docs/ is an MkDocs site (managed with uv), k8s/ and systemd/ hold deployment files, and vendor/ carries a patched axoasset and bash-preexec.

Frontend

The interface is a terminal UI. ctrl-r and the up arrow open a full-screen search (README) built with ratatui and crossterm. Shell integrations cover zsh (atuin.plugin.zsh), bash via the vendored bash-preexec, and fish and Nushell, which appear in the language breakdown along with Xonsh and PowerShell. Fluent files carry translations.

Backend & APIs

The sync server (crates/atuin-server) is an Axum application with tower-http. It uses argon2 for account passwords and exports Prometheus metrics through metrics-exporter-prometheus. The server never sees plaintext history: clients encrypt it with crypto_secretbox and manage keys with rusty_paseto and rusty_paserk (crates/atuin-common).

Locally, crates/atuin-daemon runs a gRPC service with tonic and prost. Protobufs are compiled at build time with protox, and on Linux the daemon supports socket activation through listenfd. It keeps an embedded fjall store and uses frizbee for fuzzy matching.

Data & persistence

Each machine stores history in SQLite through sqlx, with the regexp extension for regex search (crates/atuin-client). The server builds sqlx with postgres, sqlite and mysql, so self-hosters can choose a backend. Records are serialised with MessagePack (rmp, rmp-serde) before encryption.

Build, test & deploy

  • The main CI runs on Buildkite (.buildkite/pipeline.yml). GitHub Actions cover release.yml, beta-release.yml, docker.yaml, windows.yml, docs-main.yml, docs-release.yml, devcontainer.yaml and update-nix-deps.yml. .depot/ configures Depot runners.
  • Releases use cargo-dist (dist-workspace.toml). The atuin crate also carries cargo-binstall, Debian and RPM metadata. self-update is an opt-in feature, only enabled for official installer builds.
  • The server Dockerfile uses cargo-chef, pins the toolchain from rust-toolchain.toml, runs as an unprivileged atuin user, and health-checks /healthz.
  • Tests use rstest, proptest and wiremock. divan benchmarks run with CodSpeed (README badge). deny.toml and .cargo/audit.toml cover dependency policy.

Self-hosting notes

Run the atuin-server image (port 8888 by default), or use the example manifests in k8s/ (atuin.yaml, namespaces.yaml, secrets.yaml) or the systemd/atuin-server.service unit. Point clients at the server in their config. Because history is encrypted client-side, the server stores only ciphertext.

What to copy (and what not to)

Copy:

  • Local-first data with end-to-end encrypted sync. The server becomes a dumb, safe store.
  • Integration tests that drive the real server with the real client, without making the client depend on server crates.
  • Capability crates turned on by features, so packagers can build a smaller binary.
  • Agent-ready repo: AGENTS.md, skills under .claude/skills and .atuin/skills, and a devcontainer that installs Claude Code.

Don't copy blindly:

  • A daemon with gRPC, a PTY proxy and AI features add moving parts that a simple CLI does not need.
  • Supporting three server databases multiplies test cases. Most services should pick one.

For an Axum service template, see the Rust + Axum + PostgreSQL rules.

Sources & repo audit

Audited
Oct 2, 2026
Commit
d97cb8e
License
MIT

Independent analysis of repository at github.com/atuinsh/atuin. Spotted an inaccuracy? Use the claim form to request a correction.

Maintainer? Add the architecture badge to your README
architecture: stackitfast
[![Architecture on STACK IT FAST](https://stackitfast.com/badge/atuin.svg)](https://stackitfast.com/project/atuin)
Use this stack

Scaffold it with your agent

Paste this prompt into Claude Code, Cursor, Windsurf or AGY to start a project with Atuin's architecture.

  1. 1Copy the promptThe full markdown spec, with every layer and decision.
  2. 2Open your AI toolClaude Code, Cursor, Windsurf or Copilot, in a new repo.
  3. 3Paste and scaffoldUse it as the first instruction; review before you ship.
use-this-stack.md · 60 lines · 7.5 KB
# MISSION: Scaffold "Atuin" Production Architecture
You are an expert Senior Staff Software Architect and Full-Stack Engineer. Your mission is to scaffold and implement a production-grade, highly reliable, and modular codebase following the proven architecture of **Atuin**.
---
## 1. PROJECT SPECIFICATIONS & BENCHMARK
- **Reference Architecture**: Atuin
- **What It Does**: Atuin replaces shell history with a local SQLite database that records context such as exit code, directory and duration, and offers end-to-end encrypted sync between machines through a self-hostable Rust server.
- **Domain & Category**: Shell History Sync
- **Production Scale**: 2-5 people
- **Development Mode**: CLASSIC
- **Architectural Rationale**: Atuin keeps history local in SQLite and encrypts it before sync, so the Axum sync server stays a thin store; a gRPC daemon and capability crates (CLI, server, AI, dotfiles) let each part evolve behind feature flags.
- **Live Website Reference**: https://atuin.sh
- **Source Repository**: https://github.com/atuinsh/atuin
---
## 2. PRODUCTION TECH STACK
- **Full Stack Array**: Rust, Axum, sqlx, SQLite, PostgreSQL, MySQL, Tokio, gRPC, Docker, Kubernetes, Nix, Prometheus, Model Context Protocol
- **Primary Language(s)**: Rust, Shell, Fluent, PowerShell
- **License of the reference repo**: MIT
- **Frontend**: Ratatui — Terminal UI for the full-screen history search bound to ctrl-r and the up arrow, rendered with crossterm.
- **Backend & APIs**: Rust — Language for the CLI, daemon, server and every crate in crates/ (edition 2024, Rust 1.95 minimum).; Axum — HTTP framework of the atuin-server sync server, with tower-http middleware.; gRPC — atuin-daemon serves a local gRPC API with tonic and prost; protobufs are compiled at build time with protox.; PASETO — rusty_paseto and rusty_paserk handle key material, and crypto_secretbox encrypts history before it is synced.
- **Data & persistence**: SQLite — Local history database on every machine, accessed through sqlx with the regexp extension.; PostgreSQL — Sync server database; atuin-server also builds sqlx drivers for SQLite and MySQL.; Fjall — Embedded key-value store used by the daemon.
- **Infrastructure & deploy**: Docker — cargo-chef multi-stage build of atuin-server on Debian slim, running as a non-root user with a /healthz check on port 8888.; Kubernetes — Example manifests for running the sync server: atuin.yaml, namespaces.yaml and secrets.yaml.; Prometheus — Server metrics through the metrics crate and metrics-exporter-prometheus.; Buildkite — Main CI pipeline in .buildkite/pipeline.yml; GitHub Actions handle releases, Docker images, docs and Windows builds.; cargo-dist — dist-workspace.toml configures release artifacts and installers, including the optional self-update feature.; Nix — flake.nix, default.nix and atuin.nix package Atuin for Nix; update-nix-deps.yml keeps hashes current.
- **Tooling, testing & ops**: Model Context Protocol — atuin-ai depends on rmcp, the Rust MCP SDK, alongside tree-sitter shell parsers for its AI features.; AGENTS.md — Agent instructions at the root, plus skills under .claude/skills and .atuin/skills.
---
## 3. KEY ARCHITECTURAL DECISIONS (audited from https://github.com/atuinsh/atuin @ d97cb8e)
1. **Local-first SQLite, optional encrypted sync**: The README says Atuin replaces shell history with a SQLite database and offers optional, fully encrypted sync through an Atuin server. atuin-client uses sqlx with SQLite, and atuin-common brings crypto_secretbox plus PASETO crates, so the server only ever stores ciphertext.
2. **Server is a small Axum app over sqlx with three databases**: crates/atuin-server builds the atuin-server binary on axum, tower-http and sqlx with postgres, sqlite and mysql features, and exports Prometheus metrics. Its integration tests start a real server and drive it with the client's API client, kept as a dev-dependency so the CLI stays free of server dependencies.
3. **A local daemon with a gRPC API**: crates/atuin-daemon runs in the background with tonic and prost (protobufs compiled by protox at build time), an embedded Fjall store and socket activation via listenfd on Linux, so shells talk to a long-lived process instead of opening the database on every command.
4. **Workspace split by capability**: crates/* separates atuin (the CLI), atuin-client, atuin-server, atuin-daemon, atuin-domain (shared API types with optional axum handlers), atuin-history, atuin-dotfiles, atuin-kv, atuin-scripts, atuin-pty-proxy and atuin-ai, and the atuin crate turns them on through features such as sync, daemon, ai and pty-proxy.
5. **AI features built on MCP**: crates/atuin-ai depends on rmcp, the Rust Model Context Protocol SDK, plus tree-sitter-bash and tree-sitter-fish, ratatui and an SSE client (eventsource-stream), and is part of the default feature set of the atuin binary.
---
## 4. NON-NEGOTIABLE ARCHITECTURAL GUARDRAILS
1. **Monorepo & Modular Separation**:
   - Structure as a Turborepo monorepo with strict package boundaries:
     - `apps/web`: Application UI, routing, layouts, and server endpoints.
     - `packages/ui`: Shared design tokens, CSS variables, and Radix UI primitive components.
     - `packages/db`: Database schemas, client singleton, declarative migrations, and seed scripts.
     - `packages/config`: Shared TypeScript, ESLint, and build configurations.
2. **Strict Type Safety & Zero `any` Policy**:
   - Enable `strict: true`, `noImplicitAny: true`, and `strictNullChecks: true`.
   - Validate ALL external inputs, API request bodies, and query parameters with **Zod** schemas before execution.
3. **Frontend & Rendering Guidelines**:
   - Isolate interactive UI state to leaf components. Keep core pages lightweight and performant.
4. **Design System & Aesthetics**:
   - Keep every color, radius, shadow and font in a single token file (CSS variables) and consume tokens everywhere; never hardcode hex values in components.
   - Prefer crisp 1px borders and one subtle shadow scale over blurry default shadows. Pair one sans-serif for body/headings with one monospace for tags, badges, metrics, and code.
5. **Data Layer & Reliability**:
   - Write declarative schema definitions with foreign keys, composite indexes on queried filters, and automated timestamp triggers.
   - Use connection pooling and prepared statements for serverless database execution.
---
## 5. STEP-BY-STEP SCAFFOLDING ROADMAP
- **Phase 1: Workspace & Root Config**: Initialize package manager, monorepo configuration (`turbo.json`, `tsconfig.base.json`, `package.json`).
- **Phase 2: Database Schema & Client**: Set up the data layer (SQLite, PostgreSQL, Fjall): client, connection pool, models, and migration scripts.
- **Phase 3: Design Tokens & UI Primitives**: Build accessible `Button`, `Input`, `Card`, `Badge`, and layout wrappers inside `packages/ui`.
- **Phase 4: Core Application Routes & Handlers**: Implement primary authentication, user session handling, and application routes.
- **Phase 5: Quality Assurance & Build Verification**: Run `tsc --noEmit`, ESLint, Prettier, and smoke test suites to ensure zero compilation or runtime errors.
---
## 6. EXECUTION INSTRUCTIONS
1. Review all specifications, architectural guardrails, and stack choices above.
2. Present the full monorepo directory tree structure.
3. Systematically generate the complete, production-ready codebase according to the 5-phase roadmap above — starting with the root workspace setup, followed by the database schema, UI design system package, and full-stack application routes until the repository is fully scaffolded and ready to run.
Scaffolded something with this prompt?
Would you pick this stack for a shell history sync project?

Frequently asked about Atuin

What is Atuin built with?

Atuin is written in Rust. The CLI and terminal UI use ratatui and crossterm, local history lives in SQLite through sqlx, a background daemon exposes a gRPC API with tonic, and the sync server is an Axum application on PostgreSQL.

Can I self-host the Atuin sync server?

Yes. The repository builds an atuin-server Docker image with a /healthz check on port 8888, and ships Kubernetes manifests in k8s/ and systemd unit files in systemd/. The server supports PostgreSQL, SQLite and MySQL through sqlx.

Is Atuin sync encrypted?

Yes. History is encrypted on the client before it is synced; atuin-common uses crypto_secretbox for encryption and PASETO libraries for keys, and the README states the server operator cannot read synced history.

Does Atuin use Axum?

Yes. crates/atuin-server depends on axum and tower-http, and atuin-domain exposes optional axum handlers for shared server capabilities.

Does Atuin have AI features?

Yes. The atuin-ai crate is part of the default build and uses rmcp (the Rust Model Context Protocol SDK) and tree-sitter parsers for bash and fish, with a ratatui interface.

One email a month: new deep dives and stack trends

New source-audited architectures, head-to-head comparisons and the monthly stack report. No spam, unsubscribe anytime.

use-this-stack.md