Skip to content
rsdlt.dev
Go back

Building levi: A Small, Fast Git Diff Viewer in Rust, Written with Claude Code

levi is a git diff viewer for the terminal. It does one thing: browse the commits on your branch, the files each one touched, and their diffs, with fzf-style search on top. It went from an empty repository to release 0.12.0 between the night of October 15 and the afternoon of October 17. Every one of its 48 commits was written with Claude Code.

levi browsing its own history: fuzzy search, a diff with changed words marked, a code search, and Enter handing the sha to git show

This post opens a series about how it was built. It covers what levi is, the decisions that shaped it, and how I worked with the agent. The posts after it follow the build session by session.

What levi does

Three panes and a search bar:

The search bar always has focus. As you type, commits and files narrow down together. A commit matches by subject, author, sha prefix or any file it touched, so typing parse.rs answers “which commits touched parse.rs?” right away.

Two slash commands go in the same bar:

Enter prints the selected sha to stdout, so levi also works as a picker:

git show $(levi)

Why not tig or lazygit?

Those are full git clients. levi isn’t. It doesn’t stage, commit, rebase or push. It only reads history, and it’s built to do that fast on large repositories. On git.git, with 82,500 commits, the first screen shows up in about 40 ms, the full history loads in under a second, and each search takes 5–12 ms. It’s about 2,300 lines of Rust and a 1.6 MB binary.

The name fits the brief: Captain Levi from Attack on Titan, small, swift and precise. The README leans into it.

The decisions that shaped it

Before the first line of code, there was a plan. The first commit already includes docs/plan.md, and it has a decisions table that held for the whole build:

DecisionChoiceWhy
Git backendShell out to the git CLI, not git2 or gixRespects the user’s git config, needs no C build, keeps the binary small.
ScopeThe current branch, or one revisionNo --all.
Merge commitsDiff against the first parentHistory isn’t first-parent only: commits from merged branches still show.
Uncommitted changesOut, for nowNo working-tree pseudo-commit.
Fuzzy matchingnucleo-matcherfzf-compatible syntax: smart case, ^, $, ', !.
Diff renderingSimple colors, no syntax highlightingThe commit message on top and changed words marked, nothing more.

Saying no to things up front is what kept levi small. Three runtime dependencies (ratatui, nucleo-matcher and anyhow) cover the whole app.

How I built it with Claude Code

I’ve written about how I use Claude Code on a production SaaS. levi was a chance to use the same approach on a project small enough to see end to end. It will come up in every post of this series. Here’s the short version:

The series

  1. Why I built levi (this post).
  2. Night one: from zero to 0.1.0 in 90 minutes. The git layer, the three-pane TUI, background loading, fuzzy search on every core, and CI.
  3. After midnight: chasing a 55-second code search down to 0.16 seconds. The reflog, /c, loading history on every core, and narrowing the search to only the commits and files that matter.
  4. Day two: the polish that makes a TUI usable. Changed-word highlighting, mouse support, a layout for narrow terminals, levi main..HEAD, and shipping binaries for every platform.

The series covers levi up to 0.12.0. If levi gets new features worth writing about, they’ll be added here.

Try it

brew install rsdlt/tap/levi
# or
cargo binstall levi-git

Prebuilt binaries for macOS, Linux and Windows are on the releases page. levi needs git 2.31 or newer.


I’m Rodrigo Santiago, a product leader who builds. I co-founded Foambyte with my brother Diego, a brewmaster who leads the product as CPO, and I designed and built the platform: architecture, frontend, backend, mobile and infrastructure. If you need someone who can own both the product and the code, let’s talk on LinkedIn.


Share this post:

Next Post
Four Things This Week for Solo Builders: Cloudflare Void, Gemini 4 Argon, Meta Muse Wonder and Workers Flamegraphs