DEV Community

Cover image for I Used ungit for Years. Then I Built the Git GUI I Wanted.
Jiri Spac
Jiri Spac

Posted on

I Used ungit for Years. Then I Built the Git GUI I Wanted.

I was a long-time user of ungit.

And I don’t mean that I occasionally opened it when a rebase went wrong. For years, I used it for most of my interactions with Git.

ungit gave me something the command line never quite could: a spatial understanding of a repository. Branches were not just names passed to
commands. Commits had positions, merges had shapes, and the history of a project became something I could actually see.

I loved that idea.

What I didn’t love was the performance.

Over time, I became increasingly unhappy with how sluggish the experience could feel. A Git tool sits directly inside your development loop,
so even small pauses matter. When checking out a branch, moving through history, or manipulating commits causes the interface to hesitate,
it breaks your train of thought.

I didn’t want to abandon the graph-first way of working. I wanted to rebuild it around speed, animation, reliability, and the workflows I
use today.

That frustration eventually became ingit.

Git is already a graph

The Git command line is powerful, but it often makes you reconstruct the repository in your head.

Which branch contains this commit? Where did these histories diverge? What will this rebase actually do? Which commit is about to move?

Git already has the perfect data structure for answering those questions: the commit graph.

ingit makes that graph the primary interface. Commits, branches, tags, merges, worktrees, stashes, and Git operations are presented as parts
of one visual system rather than as separate dialogs.

Switching branches in ingit while preserving work in progress

Click the image to watch the branch-switching demo.

The graph is animated and virtualized, so it can remain responsive even when a repository contains a long history and many parallel
branches.

The graph responds before Git finishes

One of the most important design decisions in ingit is that the interface should respond at the speed of thought, not at the speed of a
subprocess.

When you start an operation, ingit predicts the resulting graph and animates toward it immediately. The real Git command still runs
underneath. When it finishes, ingit reads the authoritative repository state and reconciles the prediction with reality.

That means operations such as these can feel immediate:

  • Checkout
  • Merge
  • Rebase
  • Cherry-pick
  • Revert
  • Uncommit
  • Branch creation and movement

Previewing a merge in ingit

The predicted result is shown immediately, while real Git remains the source of truth.

Optimistic interfaces are common in web applications, but they are much less common in developer tools. In a Git GUI, they make an enormous
difference. Instead of clicking a button and waiting to discover what happened, you see the intended transformation as part of the action
itself.

If an operation fails, ingit does not pretend otherwise. It reconciles back to the real repository and shows the error. The animation is a
prediction, not a replacement for Git.

Branch switching without losing your flow

Switching branches while you have uncommitted changes is one of those everyday Git interactions that should feel simple but often doesn’t.

ingit keeps those changes visible while the checkout is happening. The working-tree state moves toward its new position in the graph instead
of disappearing and then suddenly reappearing elsewhere.

That sounds like a small visual detail, but it preserves continuity. Your work never appears to vanish.

ingit also treats linked worktrees as first-class parts of the repository:

Linked Git worktrees displayed in ingit

You can see which branch is checked out in each worktree, create new linked worktrees, switch between them, and remove them without leaving
the graph.

Stashes receive similar treatment. Instead of being opaque entries in a list, they can be inspected visually, including their affected files
and diffs:

Inspecting a stash in ingit

Files can be applied individually, an entire stash can be restored, and a safe checkout mode can preserve current work before switching.

A Time Machine for Git

Git’s reflog is one of its best safety nets, but its command-line presentation makes it feel more intimidating than it should.

ingit turns the reflog into a visual Time Machine. Commits and branches that no longer appear in the ordinary graph can still be found,
inspected, and recovered.

Recovering lost work with the ingit Time Machine

Click the image to watch a lost commit being recovered.

This is especially useful after a reset, rebase, deleted branch, or experimental sequence of operations. The work usually still exists. The
difficult part is knowing where to look.

A visual reflog makes recovery feel less like Git archaeology.

More than a history viewer

The graph may be the center of ingit, but the goal is to support the complete daily workflow.

You can inspect diffs, stage individual files, discard changes, amend commits, create commits, and push without switching tools.

Finishing a change with staging, commit, and push controls

Other integrations add context directly to the graph:

  • Semantic icons help distinguish fixes, features, merges, experiments, and other commit types.
  • GitHub avatars identify commit authors.
  • Pull requests and live CI statuses appear alongside the relevant history.
  • Claude Code and Codex sessions can be detected and focused from the repository view.

The aim is not to hide Git. It is to put the information required to make a decision in one place.

Plain Git underneath

I don’t want a Git GUI to create a second, competing version of my repository.

ingit uses ordinary Git repositories and ordinary Git commands. There is no proprietary repository format, separate history database, or
persistent daemon that must remain alive.

The CLI starts a local server, opens the interface in your browser, and reads the repository directly. If you later open the same repository
in another Git client—or return to the command line—everything is exactly where you expect it to be.

Git remains the source of truth.

Built by agents, steered by taste

One unusual detail about the current ingit rewrite is that its code has been written by AI coding agents.

That does not mean the product was generated from a single prompt or developed on autopilot. The difficult work is still deciding what
should happen, identifying awkward interactions, testing the result against real repositories, and repeatedly refining small visual details.

A line entering the wrong side of a commit node sounds trivial until several branches overlap and the graph becomes hard to read. Much of
the work on ingit has involved teaching the layout system rules that humans notice instinctively:

  • Parallel lines should remain visible.
  • Connections should not unnecessarily cross.
  • Branches should receive more space when the screen can provide it.
  • Operations should preserve visual continuity.
  • Animations should explain what changed rather than merely decorate it.

AI agents make rapid iteration possible. Human taste decides which iterations are worth keeping.

Try ingit

ingit is open source, MIT licensed, and available for Linux, macOS, and Windows.

Install the CLI from npm:

  npm install --global @ingit/cli
Enter fullscreen mode Exit fullscreen mode

Then run it inside any Git repository:

cd path/to/your/repository
ingit

The local interface will open in your browser.

ungit showed me how valuable a graph-first Git interface could be. ingit is my attempt to carry that idea forward with the responsiveness,
animation, and workflow integration I always wanted.

If you have ever looked at a Git history and thought, “I understand this better when I can see it,” I would love for you to try it.

Top comments (0)