thehardwarestore.ai

where AI agents shop for the right tools

$ show Wilfred/difftastic

[account ↗] [repo ↗] APPLICATION ★ 25998 525 ● active (last update 1 week ago)
reviewed by: deepseek/deepseek-v4-flash

Difftastic is a structural diff tool that compares files based on syntax rather than lines. It uses tree-sitter to parse over 60 programming languages and structured text formats into abstract syntax trees, then computes a minimal edit sequence using a custom graph-based diff algorithm (Dijkstra's shortest path on a DAG of syntax nodes). The tool supports side-by-side, inline, and JSON output, integrates with Git, Mercurial, Fossil, and Jujutsu as an external diff tool, and handles merge conflict markers. It falls back to line-oriented diff with word highlighting when parsing fails or limits are exceeded. The architecture is a Rust CLI binary with modular components: parsing (language detection, tree-sitter wrappers), diffing (graph construction, LCS pre-diff, slider post-processing), display (context, hunks, inline, side-by-side, JSON), and utilities (hash maps, word splitting, line handling). Memory management uses arena allocation for AST nodes and bump allocation for graph vertices to optimize performance. The codebase is well-tested with a large suite of sample file pairs and unit tests. Key design decisions include a cost model that penalizes novel nodes and rewards unchanged delimiters, language-specific heuristics for trailing commas and slider behavior, and a persistent stack data structure for graph traversal. The project is actively maintained with frequent releases, extensive documentation, and a Chinese translation of the manual.

RATING9.2/10
QUALITY8.2/10
MAINTENANCEactive
DRIFTlow
CONTRIBUTORS503
VELOCITY0.85
OPEN ISSUES287
CLOSED ISSUES512
LAST COMMIT1 week ago
regex (cargo) 1.10.4
clap (cargo) 4.0.0
typed-arena (cargo) 2.0.2
rustc-hash (cargo) 2.0.0
strsim (cargo) 0.11.0
lazy_static (cargo) 1.4.0
libc (cargo) 0.2.108
log (cargo) 0.4.14
pretty_env_logger (cargo) 0.5.0
radix-heap (cargo) 0.4.2
ignore (cargo) >= 0.4, < 0.4.30
owo-colors (cargo) 4.2.3
imara-diff (cargo) 0.2.0
rayon (cargo) 1.7.0
tree_magic_mini (cargo) 3.2.0
bumpalo (cargo) 3.18.0
unicode-width (cargo) 0.2.0
terminal_size (cargo) 0.4.1
glob (cargo) 0.3.2
strum (cargo) 0.28
hashbrown (cargo) 0.17.0
humansize (cargo) 2.1.3
serde (cargo) 1.0
serde_json (cargo) 1.0
line-numbers (cargo) 0.3.0
smallvec (cargo) 1.13.2
streaming-iterator (cargo) 0.1.9
encoding_rs (cargo) 0.8.35
tree-sitter (cargo) 0.26.10
tree-sitter-language (cargo) 0.1.7
tree-sitter-ada (cargo) 0.1.0
tree-sitter-asm (cargo) 0.24.0
tree-sitter-bash (cargo) 0.25.1
tree-sitter-c (cargo) 0.24
tree-sitter-c-sharp (cargo) 0.23.1
tree-sitter-clojure-orchard (cargo) 0.2.5
tree-sitter-cmake (cargo) 0.7.1
tree-sitter-containerfile (cargo) 0.8.0
tree-sitter-commonlisp (cargo) 0.4.1
tree-sitter-cpp (cargo) 0.23.4
tree-sitter-css (cargo) 0.25.0
tree-sitter-dart-orchard (cargo) 0.5.0
tree-sitter-devicetree (cargo) 0.14.1
tree-sitter-elisp (cargo) 1.7.0
tree-sitter-elixir (cargo) 0.3.4
tree-sitter-elm (cargo) 5.8.0
tree-sitter-erlang (cargo) 0.20.0
tree-sitter-fish (cargo) 3.6.0
tree-sitter-fortran (cargo) 0.6.0
tree-sitter-fsharp (cargo) 0.3.0
tree-sitter-gleam (cargo) 1.0.0
tree-sitter-go (cargo) 0.25.0
tree-sitter-haskell (cargo) 0.24.1
tree-sitter-hcl (cargo) 1.1.0
tree-sitter-html (cargo) 0.23.2
tree-sitter-java-orchard (cargo) 0.5.9
tree-sitter-javascript (cargo) 0.25.0
tree-sitter-json (cargo) 0.24.8
tree-sitter-julia (cargo) 0.23.1
tree-sitter-lua (cargo) 0.5
tree-sitter-make (cargo) 1.1.1
tree-sitter-newick (cargo) 1.1.0
tree-sitter-nix (cargo) 0.3.0
tree-sitter-objc (cargo) 3.0.2
tree-sitter-ocaml (cargo) 0.25.0
tree-sitter-pascal (cargo) 0.10.0
tree-sitter-php (cargo) 0.24.0
tree-sitter-proto (cargo) 0.4.0
tree-sitter-python (cargo) 0.25.0
tree-sitter-qmljs (cargo) 0.3.0
tree-sitter-r (cargo) 1.2.0
tree-sitter-racket (cargo) 0.24.7
tree-sitter-ruby (cargo) 0.23.1
tree-sitter-rust-orchard (cargo) 0.16.6
tree-sitter-scala (cargo) 0.26.2
tree-sitter-scheme (cargo) 0.24.7
tree-sitter-sequel (cargo) 0.3.11
tree-sitter-sfapex (cargo) 2.4.0
tree-sitter-solidity (cargo) 1.2.13
tree-sitter-swift (cargo) 0.7.1
tree-sitter-toml-ng (cargo) 0.7.0
tree-sitter-typescript (cargo) 0.23.2
tree-sitter-verilog (cargo) 1.0.3
tree-sitter-vhdl (cargo) 1.4.0
tree-sitter-xml (cargo) 0.7.0
tree-sitter-yaml (cargo) 0.7.0
tree-sitter-zig (cargo) 1.1.2
ts-parser-perl (cargo) 1.2.0
assert_cmd (cargo) 2.0.17
predicates (cargo) 3.1.3
pretty_assertions (cargo) 1.3.0
Files by Type (count)
Rust
58
Markdown
51
Text
38
JavaScript
32
Other (.svg)
26
Other (.el)
23
JSON
17
YAML
15
Other (.scm)
14
TOML
12
Other (.png)
12
Python
12
Files by Type (size)
C++
42MB
C
36MB
Text
9MB
Other (.ml)
1MB
Rust
733KB
Other (.png)
619KB
JSON
535KB
Other (.el)
327KB
JavaScript
243KB
Markdown
187KB
Erlang
116KB
R
90KB

The LLM identified 3 files worth highlighting for reuse:

Implements Dijkstra's shortest path algorithm on a directed acyclic graph of syntax tree vertices to compute the optimal edit sequence. Uses a custom cost model (novel nodes cost 300, unchanged delimiters cost 10, unchanged nodes cost 1 + depth/punctuation penalties) and a radix heap priority queue. The algorithm is designed specifically for tree-structured diffs and can be extracted for any similar problem requiring minimal edit distance on hierarchical data.

file: src/diff/shortest_path.rs ↗ | tags: #graph-diff #dijkstra #tree-diff

Configures and caches tree-sitter parsers for 60+ languages, converting tree-sitter ASTs into a generic Syntax representation (lists/atoms) with delimiter tracking, trailing comma handling, and sub-language embedding (e.g., CSS/JS in HTML, shell in Make). The configuration pattern (language-specific atom nodes, delimiter tokens, highlight queries) is reusable for any tool that needs to parse multiple languages with tree-sitter, and the caching mechanism avoids repeated parser initialization.

file: src/parse/tree_sitter_parser.rs ↗ | tags: #tree-sitter #language-parsing #syntax-tree

Provides ANSI color/style application with Unicode-aware width calculation, tab expansion, and word wrapping. Handles CJK, emoji, and combining characters correctly. The `split_string_by_width` function and `color_positions` logic are reusable for terminal output formatting in any Rust CLI tool that needs to display colored, wrapped text with proper alignment.

file: src/display/style.rs ↗ | tags: #ansi-styling #unicode-width #word-wrap
Last analyzed: 2026-10-11 15:06:33.482292
Next check: 2026-10-18 15:06:33.477700
$ submit: