How to Integrate External Diff Tools with Lazygit: Delta and Difft Configuration Guide

Lazygit integrates with external diff tools by treating them as pagers or full-diff drivers, executing commands inside a pseudo-terminal (PTY) to preserve color output and hyperlinks, and dynamically injecting Git's diff.external configuration when required.

Lazygit provides native support for lazygit external diff tools integration through a flexible pager configuration system in the jesseduffield/lazygit repository. By leveraging Git's diff.external mechanism and running commands inside a pseudo-terminal, Lazygit enables syntax-highlighted diffs and advanced comparison features directly within the terminal UI.

Understanding the Integration Architecture

Lazygit's integration operates through four distinct layers that translate user configuration into rendered diff output.

User Configuration Layer

Users declare external tools in ~/.config/lazygit/config.yml under the git.pagers array. Each entry specifies either a pager for piped output (suitable for delta) or an externalDiffCommand for full diff drivers (required for difft).

git:
  pagers:
    - pager: delta --dark --paging=never
    - externalDiffCommand: difft --color=always

According to the source code documentation in docs/Custom_Pagers.md, this configuration supports multiple entries that can be cycled at runtime using the | key.

The PagerConfig Object

In pkg/config/pager_config.go, the PagerConfig struct parses these settings and exposes helper methods to retrieve the active command. The GetExternalDiffCommand() method returns the command string when an external diff driver is configured, as shown in lines 60-66.

// pkg/config/pager_config.go
func (self *PagerConfig) GetExternalDiffCommand() string {
    currentPagerConfig := self.currentPagerConfig()
    if currentPagerConfig == nil {
        return ""
    }
    return currentPagerConfig.ExternalDiffCommand
}

Similarly, GetPagerCommand() returns pager commands such as delta with user-specified flags, while GetUseExternalDiffGitConfig() checks whether to fall back to Git's global settings.

Git Diff Command Construction

The DiffCommands.DiffCmdObj function in pkg/commands/git_commands/diff.go constructs the actual git diff invocation. When GetExternalDiffCommand() returns a non-empty string, Lazygit injects diff.external=<cmd> into Git's configuration and appends the --ext-diff flag to force Git to use the external driver.

// pkg/commands/git_commands/diff.go
func (self *DiffCommands) DiffCmdObj(diffArgs []string) *oscommands.CmdObj {
    extDiffCmd := self.pagerConfig.GetExternalDiffCommand()
    useExtDiff := extDiffCmd != ""
    useExtDiffGitConfig := self.pagerConfig.GetUseExternalDiffGitConfig()
    
    return self.cmd.New(
        NewGitCmd("diff").
            ConfigIf(useExtDiff, "diff.external="+extDiffCmd).
            ArgIfElse(useExtDiff || useExtDiffGitConfig, "--ext-diff", "--no-ext-diff").
            // ... additional arguments
    )
}

Pseudo-Terminal (PTY) Execution

When a pager or external diff driver is required, Lazygit executes the Git command inside a pseudo-terminal via Gui.newPtyTask in pkg/gui/pty.go. This forces Git to treat the output as an interactive terminal, enabling color codes, hyperlinks, and proper formatting that would otherwise be stripped in pipe mode.

// pkg/gui/pty.go
func (gui *Gui) newPtyTask(view *gocui.View, cmd *exec.Cmd, prefix string) error {
    pager := gui.stateAccessor.GetPagerConfig().GetPagerCommand(width)
    externalDiffCommand := gui.stateAccessor.GetPagerConfig().GetExternalDiffCommand()
    useExtDiffGitConfig := gui.stateAccessor.GetPagerConfig().GetUseExternalDiffGitConfig()
    
    if pager == "" && externalDiffCommand == "" && !useExtDiffGitConfig {
        // No pager / external diff → run without PTY
        return gui.newCmdTask(view, cmd, prefix)
    }
    // ... PTY execution logic follows
}

Configuring Delta as a Syntax-Highlighting Pager

Delta functions as a pager that receives diff output via stdin. To enable delta with hyperlink support for file navigation, configure the pager with the lazygit-edit:// protocol handler as documented in docs/Custom_Pagers.md.


# ~/.config/lazygit/config.yml

git:
  pagers:
    - pager: delta --dark --paging=never \
             --line-numbers --hyperlinks \
             --hyperlinks-file-link-format="lazygit-edit://{path}:{line}"

When viewing a file diff in Lazygit, delta renders syntax-highlighted output with clickable line numbers. Selecting a hyperlink opens the file at the specific line in your configured editor, provided your terminal supports the lazygit-edit:// protocol.

Configuring Difft as an External Diff Driver

Difftastic (difft) requires the full diff stream and operates as an external diff driver rather than a pager. Configure it using the externalDiffCommand key in your Lazygit configuration.

git:
  pagers:
    - externalDiffCommand: difft --color=always --display=inline

With this configuration, pressing Ctrl-t (<c-t>) on a file invokes git difftool --no-prompt, which Git routes through difft because of the injected diff.external setting. Lazygit displays the processed structural diff output in the main view.

Advanced Configuration Options

Using Git's Global diff.external Setting

Rather than specifying the command directly in Lazygit's configuration, you can instruct Lazygit to respect Git's global diff.external setting by enabling useExternalDiffGitConfig.

git:
  pagers:
    - useExternalDiffGitConfig: true

If you have previously configured git config --global diff.external difft, Lazygit automatically invokes that external driver when useExternalDiffGitConfig is enabled, as implemented in the DiffCmdObj logic referenced above.

Cycling Between Multiple Pagers

Lazygit supports defining multiple pager configurations and cycling between them at runtime. Press the | (pipe) key to rotate through the list defined under git.pagers. The currently active pager appears in the UI status bar, allowing quick switching between delta for syntax highlighting and standard diff output.

Summary

  • Lazygit external diff tools integration relies on three core components: the PagerConfig object in pkg/config/pager_config.go, dynamic Git command construction in DiffCmdObj, and PTY execution in newPtyTask.
  • Delta operates as a pager receiving stdin, requiring the pager configuration key with optional hyperlink formatting for editor integration via lazygit-edit:// URLs.
  • Difft requires full diff stream access and uses the externalDiffCommand key, invoked via Git's diff.external mechanism with the --ext-diff flag.
  • Commands execute inside a pseudo-terminal when external tools are active, ensuring color output and terminal features render correctly.
  • Multiple pagers can be defined and cycled using the | key, with useExternalDiffGitConfig providing fallback to global Git settings as documented in docs/Config.md.

Frequently Asked Questions

Can I use both delta and difft simultaneously in Lazygit?

No, you cannot use both tools simultaneously for the same diff operation. However, you can define both in your git.pagers array and press | to cycle between them at runtime according to the source code in pkg/config/pager_config.go. Delta works best as a pager for syntax-highlighted patches, while difft excels at structural comparisons requiring the externalDiffCommand configuration.

Why does Lazygit use a pseudo-terminal for external diff tools?

Lazygit executes external diff commands inside a pseudo-terminal (PTY) to force Git into "terminal mode" rather than pipe mode. According to the implementation in pkg/gui/pty.go, this ensures tools like delta receive the isatty() response they expect, enabling color codes, hyperlinks, and formatted output that would otherwise be stripped when Git detects a non-interactive pipe.

Configure delta with the --hyperlinks-file-link-format="lazygit-edit://{path}:{line}" argument in your config.yml. This generates lazygit-edit:// URLs that Lazygit intercepts. Ensure your terminal emulator supports hyperlink protocols and that Lazygit's os.open command is configured to handle the lazygit-edit scheme with your preferred editor.

What happens if no external diff tool is configured?

When git.pagers is empty or no pager matches the current context, Lazygit falls back to standard Git diff output without PTY execution. The raw diff displays in the main view without syntax highlighting, and no external processes are spawned for diff generation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →