Claude Code for Difftastic — Workflow Guide

Written by Michael Lip · Solo founder of Zovo · $400K+ on Upwork · 100% JSS Join 50+ builders · More at zovo.one

The Setup

You are using Difftastic as your diff tool — it understands code structure and shows syntax-aware diffs instead of line-based text diffs. When Claude Code generates code changes, reviewing them with Difftastic produces cleaner output that highlights what actually changed semantically. The challenge is configuring Git to use Difftastic and teaching Claude Code to work with its output format.

What Claude Code Gets Wrong By Default

  1. Generates line-based diff instructions. Claude describes changes as “change line 42” or provides unified diff patches. Difftastic shows structural changes (moved expressions, renamed variables) that do not map to line numbers cleanly.

  2. Assumes git diff output format. Claude parses or generates standard unified diff format with + and - prefixes. Difftastic’s side-by-side structural output uses a completely different format that existing diff parsing tools cannot handle.

  3. Ignores the performance cost on large repos. Claude triggers git log -p or git diff on entire repositories. Difftastic is slower than standard diff because it parses ASTs. Claude should limit diff scope when using Difftastic.

  4. Does not set up the Git integration. Claude installs Difftastic but does not configure Git to use it. Without the proper GIT_EXTERNAL_DIFF setting, git diff still uses the default text differ.

The CLAUDE.md Configuration

# Difftastic Structural Diff Setup

## Diff Tool
- Diff: Difftastic (difft) — structural, syntax-aware diffs
- Git config: core.external-diff = difft
- Pager: GIT_PAGER=less for difftastic output

## Difftastic Rules
- Set GIT_EXTERNAL_DIFF=difft for git diff commands
- Or configure globally: git config --global diff.external difft
- Use --color=always for terminal output
- Limit diff scope to changed files, not entire repo
- For CI/patches, use standard diff: GIT_EXTERNAL_DIFF= git diff
- Difftastic is read-only — it shows diffs, does not apply them

## Conventions
- Code review: git diff HEAD~1 (uses difftastic for structural view)
- Quick line diff: GIT_EXTERNAL_DIFF= git diff (bypass difftastic)
- Supported languages: JS, TS, Python, Rust, Go, and 30+ others
- Binary files and generated code: skip with .gitattributes diff=binary
- Use git log -p --ext-diff for difftastic in log output

Workflow Example

You want to review Claude Code’s changes before committing. Prompt Claude Code:

“Show me a structural diff of all changes in the current working directory, then summarize what was modified semantically — not just which lines changed.”

Claude Code should run GIT_EXTERNAL_DIFF=difft git diff to show the structural diff, then provide a summary based on the semantic changes (e.g., “renamed function X to Y,” “added parameter Z to method A”) rather than “changed lines 15-20.”

Common Pitfalls

  1. Difftastic breaking Git patch workflows. Claude tries to pipe git diff output with Difftastic enabled into git apply. Difftastic output is for human reading, not machine patching. Disable it for patch creation: GIT_EXTERNAL_DIFF= git diff > changes.patch.

  2. Performance on monorepos. Claude runs git diff --stat across thousands of files with Difftastic enabled. The structural parsing is expensive per file. Use --diff-filter=M to limit to modified files or scope to specific directories.

  3. Missing language support. Claude assumes Difftastic handles every file type structurally. For unsupported languages, it falls back to text-based diff. Check difft --list-languages to know which files get structural diffing and which fall back to line diff.