mrkeyoor.com_
Tue 22 Sept 22:32 UTC
PyPIDataupdated 22 Sept 2026

daff review

daff 1.4.2 compares related tables by rows and columns, then emits the differences in a tabular format that can also be applied as a patch. Its command line handles CSV, TSV, newline-delimited JSON, and SQLite, can render HTML, and can perform a three-way merge from a common parent. It works best on revisions of the same dataset, where keys or row order give the aligner something dependable. The code originates in Haxe and is translated into Python and several other languages. Version 1.4.2 only trims material from the npm package, so the published Python behavior did not gain a new feature in that release. Our Python 3.12 install added one pure-Python package with no declared dependencies.

Verdict

daff 1.4.2 installed in 0.2 seconds as 1 package using 1 MB, imported in 0.30 seconds, and had 0 audit findings in our sandbox. Install it for keyed revisions of CSV-like tables that need a readable, applicable patch; choose a dataframe comparator when types and numeric tolerance carry the decision.

We installed it

Lab card: what happened when we installed daffScreenshot of daff documentation
Install✓ · 0.2s1 package on disk · 1 MB
Importimport daff in 0.30s · pure Python
Known vulns0(pip-audit)

Answers from our run

Does daff install cleanly?

Yes. In a fresh container with an empty cache, pip install daff finished in 0.2s, leaving 1 package and 1 MB on disk. pip-audit reported no known vulnerabilities.

What does daff need to run?

Python 3.x, and nothing compiled: it is pure Python. In our run import daff succeeded in 0.30s.

daff or csv-diff: which should you use?

csv-diff: Choose it for a smaller key-based CSV or JSON report when patching and three-way merge are unnecessary. daff 1.4.2 installed in 0.2 seconds as 1 package using 1 MB, imported in 0.30 seconds, and had 0 audit findings in our sandbox.

When should you not use daff?

The datasets came from unrelated systems and need entity resolution. daff is optimized for versions of the same table, not probabilistic matching between independent exports.

API stability4/5daff 1.4.2 retains the established diff, patch, merge, trim, render, and git commands plus the highlighter table used for reports and patches. The latest release note says the change only trims the npm package, so Python users received no documented API shift. The safer contract is the CLI: PyPI still carries an Alpha classifier, the import surface is generated from Haxe, and no py.typed marker tells Python tooling which signatures are supported.
Docs4/5The README lists every CLI mode, supported format, output option, primary-key flag, ordering rule, exit status, SQLite table syntax, patch warning, render switch, and git integration command. It also links the tabular-diff specification and a live demo, and the documentation URL returned HTTP 200. The direct library tutorial is written around JavaScript TableView and CompareFlags objects, leaving Python callers to translate examples or read generated code.
Maintenance3/5PyPI shows 1.4.2 published on May 4, 2025, and its release note concerns npm packaging rather than Python behavior. GitHub reports a later push on May 27, 2026, 923 stars, and 47 open issues and pull requests combined; the repository is unarchived. Source work is recent enough to reject an abandoned label, but the Python release cadence and multi-language build process give adopters less certainty than an actively released Python-first comparator.
Ecosystem3/5The supplied download snapshot is 5,816,860 weekly downloads, and GitHub reports 923 stars. daff's highlighter format works across its Python, JavaScript, Java, C#, C++, Ruby, and PHP translations, and the CLI can act as a Git CSV diff and merge driver. Modern Python data stacks still need conversion for pandas dtypes, Arrow, Parquet, or warehouse tables, and the wheel offers no py.typed metadata for editor support.

Use it if

  • CSV reviews need cell-level inserts, deletes, moves, and updates instead of a line diff that loses column alignment.
  • A diff must double as an input that another job can apply to a copy of the original table.
  • Two edited tables share a common ancestor and need a three-way merge rather than last-writer-wins replacement.
  • The same tabular diff format must be rendered in HTML, used from a shell, or consumed by another supported language build.
Skip it if

Setup reality

We installed daff 1.4.2 in a fresh Python 3.12 Bookworm sandbox. Installation completed in 0.2 seconds, left 1 package, and used 1 MB on disk. The wheel is pure Python with 0 direct dependencies. import daff worked in 0.30 seconds, and pip-audit found 0 known vulnerabilities. The distribution does not declare a Python version floor and does not ship py.typed, so static checkers cannot assume the generated module is typed.

No account, daemon, or configuration file is required. The first real choice is row identity. CSV input is ordered by default, while JSON-style input is unordered. Add one or more --id columns when the table has a stable primary key, and use --unordered only when position carries no meaning. Without a key, daff aligns similar rows heuristically; inspect that alignment before treating its output as an automated data change.

The highlighter table produced by diff is also the patch format. Keep marker columns intact and send patch output to a new file first. patch --inplace and merge --inplace modify the target, which is a poor default for CI or one-off recovery work. --fail-if-diff returns 0 for equality, 1 for a detected difference, and 2 for a processing error. Disable terminal color when logs or another program will consume stdout.

SQLite comparison needs a table name when it cannot be inferred; renamed tables use the documented old:new form. The CLI does not read Parquet or preserve Excel formulas and formatting. Direct Python use exposes translated classes rather than a Python-first dataframe contract, and the package has no py.typed marker. Pin 1.4.2 and favor the command boundary unless you are prepared to inspect generated signatures during upgrades.

Patterns

Compare two ordered CSV revisions compare-csv

daff before.csv after.csv

CSV rows are ordered by default, so a move can appear as a structural change even when values stay the same.

Align records by an ID column set-primary-key

daff diff --id customer_id before.csv after.csv

Repeat `--id` for a composite key; stable keys make alignment safer than similarity matching.

Compare keyed rows without position ignore-row-order

daff diff --unordered --id id before.csv after.csv

Use unordered mode only when row position has no meaning, and pair it with a key when duplicates are possible.

Write an applicable tabular diff save-patch

daff --output changes.csv before.csv after.csv

The output is both a human-readable highlighter table and patch input, so its marker columns must remain unchanged.

Apply changes into a separate file apply-patch

daff patch before.csv changes.csv > after.csv

Writing a new file avoids the destructive behavior of `--inplace` and leaves the original available for review.

Merge two edits from one parent merge-tables

daff merge parent.csv ours.csv theirs.csv > merged.csv

The first input must be the common ancestor; unrelated tables do not provide the three-way comparison daff expects.

Distinguish changes from processing errors gate-ci

daff diff --fail-if-diff --no-color expected.csv actual.csv

Exit status 0 means equal, 1 means different, and 2 means daff could not process the comparison.

Exclude volatile columns ignore-columns

daff diff --ignore updated_at --ignore exported_at before.csv after.csv

Ignored fields disappear from the decision, so reserve this for values that the review and patch truly do not need.

Report only cell updates filter-updates

daff diff --act update before.csv after.csv

The filtered report omits inserts and deletes and therefore should not be saved as a complete migration patch.

Turn a saved diff into HTML render-html

daff render --output changes.html changes.csv

Add `--fragment` for embedding in an existing page or `--css` to write the matching stylesheet.

Diff a named SQLite table compare-sqlite

daff diff --input-format sqlite --table customers old.db new.db

A renamed table uses `--table old_name:new_name`; daff compares table contents rather than the full database schema.

Register CSV diff and merge drivers configure-git

daff git csv

This writes Git configuration, so inspect `daff git` instructions first when repository-wide driver policy is shared.

Alternatives

PackageRegistryPick it when
csv-diffPyPIChoose it for a smaller key-based CSV or JSON report when patching and three-way merge are unnecessary.
datacompyPyPIChoose it for pandas or Spark comparisons that need join columns, numeric tolerances, and dataframe-oriented reports.
deepdiffPyPIChoose it when the objects are nested Python or JSON structures rather than rectangular tables.

More data guides

numpy · fsspec · pandas · sqlalchemy · pyarrow · lxml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.