22 releases

0.9.0 Oct 9, 2025
0.8.1 Jun 17, 2025
0.8.0 Nov 21, 2024
0.7.0 May 7, 2024
0.2.4 Feb 3, 2019

#49 in Text processing

Download history 53174/week @ 2025-09-01 47287/week @ 2025-09-08 48325/week @ 2025-09-15 51551/week @ 2025-09-22 59001/week @ 2025-09-29 48136/week @ 2025-10-06 46943/week @ 2025-10-13 45516/week @ 2025-10-20 58333/week @ 2025-10-27 59026/week @ 2025-11-03 44833/week @ 2025-11-10 57005/week @ 2025-11-17 51787/week @ 2025-11-24 50432/week @ 2025-12-01 52596/week @ 2025-12-08 9044/week @ 2025-12-15

176,637 downloads per month
Used in 188 crates (27 directly)

MIT license

94KB
1K SLoC

prettydiff

Crate docs.rs

Side-by-side diff for two files in Rust. App && Library.

Examples

Slice diff

use prettydiff::diff_slice;

println!("Diff: {}", diff_slice(&[1, 2, 3, 4, 5, 6], &[2, 3, 5, 7]));
println!(
    "Diff: {}",
    diff_slice(&["q", "a", "b", "x", "c", "d"], &["a", "b", "y", "c", "d", "f"])
);
println!(
    "Diff: {}",
    diff_slice(&["a", "c", "d", "b"], &["a", "e", "b"])
);

diff_slice

Get vector of changes:

use prettydiff::diff_slice;

assert_eq!(
    diff_slice(&["q", "a", "b", "x", "c", "d"], &["a", "b", "y", "c", "d", "f"]).diff,
    vec![
        DiffOp::Remove(&["q"]),
        DiffOp::Equal(&["a", "b"]),
        DiffOp::Replace(&["x"], &["y"]),
        DiffOp::Equal(&["c", "d"]),
        DiffOp::Insert(&["f"]),
    ]
);

Diff line by chars or words

diff_chars

use prettydiff::{diff_chars, diff_words};

println!("diff_chars: {}", diff_chars("abefcd", "zadqwc"));
println!(
    "diff_chars: {}",
    diff_chars(
        "The quick brown fox jumps over the lazy dog",
        "The quick brown dog leaps over the lazy cat"
    )
);
println!(
    "diff_chars: {}",
    diff_chars(
        "The red brown fox jumped over the rolling log",
        "The brown spotted fox leaped over the rolling log"
    )
);
println!(
    "diff_chars: {}",
    diff_chars(
        "The red    brown fox jumped over the rolling log",
        "The brown spotted fox leaped over the rolling log"
    )
    .set_highlight_whitespace(true)
);
println!(
    "diff_words: {}",
    diff_words(
        "The red brown fox jumped over the rolling log",
        "The brown spotted fox leaped over the rolling log"
    )
);
println!(
    "diff_words: {}",
    diff_words(
        "The quick brown fox jumps over the lazy dog",
        "The quick, brown dog leaps over the lazy cat"
    )
);

Diff lines

diff_lines

use prettydiff::diff_lines;

let code1_a = r#"
void func1() {
    x += 1
}

void func2() {
    x += 2
}
    "#;
let code1_b = r#"
void func1(a: u32) {
    x += 1
}

void functhreehalves() {
    x += 1.5
}

void func2() {
    x += 2
}

void func3(){}
"#;
println!("diff_lines:");
println!("{}", diff_lines(code1_a, code1_b));

Diff Lines with Custom Config

diff_lines

use prettydiff::{diff_lines, text:ContextConfig};
use owo_colors::Style;

let context = ContextConfig {
        context_size: 2,
        skipping_marker: "...",
        remove_color: Style::new().red().underline(),
        insert_color: Style::new().purple().bold(),
    };

let code1_a = r#"
void func1() {
    x += 1
}

void func2() {
    x += 2
}
    "#;
let code1_b = r#"
void func1(a: u32) {
    x += 1
}

void functhreehalves() {
    x += 1.5
}

void func2() {
    x += 2
}

void func3(){}
"#;
println!("diff_lines:");
println!("{}", diff_lines(code1_a, code1_b).format_with_context(Some(context), true));

Dependencies

~0.2–2.4MB
~40K SLoC