---
title: "Compare PDFs and highlight differences in C#"
url: https://recursiveai.org/onediff/cookbook/compare-pdf-highlight-changes/
description: "Compare text-bearing PDFs in C# and highlight differences on the new pages, with old text in pop-ups and a downloadable .NET example."
version: "1.0.1"
---

# Compare PDFs and highlight differences in C#

**OneDiff** is a free, open-source diff library for .NET from Recursive AI. MIT or Apache-2.0, no native dependencies.

[NuGet](https://www.nuget.org/packages/RecursiveAI.OneDiff.Pdf) · [GitHub](https://github.com/recursive-ai-oss/onediff-csharp) · [Docs](https://recursiveai.org/onediff/docs/) · [Download example (.zip)](https://recursiveai.org/onediff/cookbook/compare-pdf-highlight-changes/compare-pdf-highlight-changes.zip)

Highlight text changes on the new PDF. `old.pdf` and `new.pdf` are in the zip; scans need a separate OCR reader.

```shell
dotnet add package RecursiveAI.OneDiff.Pdf
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

```csharp
using OneDiff.Documents;
using OneDiff.Pdf;

PdfRedline.Register();
Redline.Create(
    "old.pdf", "new.pdf", "markup.pdf");
Console.WriteLine("Wrote markup.pdf");
```

```text
Wrote markup.pdf
```

`old.pdf` and `new.pdf` are generated, redistributable one-page samples in the zip. Their complete text is “Pay in 30 days.” and “Pay in 60 days.” respectively. The program writes `markup.pdf`; open it in a PDF viewer that displays annotations to see the highlight and its old-text pop-up. A PDF without a text layer is refused rather than compared as an empty document.

Unzip [the example](https://recursiveai.org/onediff/cookbook/compare-pdf-highlight-changes/compare-pdf-highlight-changes.zip), then `dotnet run`.

## Variations

**Render a new redline PDF instead of annotating the new pages.** Uses the same two input PDFs.

```csharp
using OneDiff.Documents;
using OneDiff.Pdf;
PdfRedline.Register();
var comparison = Comparison.Of("old.pdf", "new.pdf");
comparison.SaveAs("redline.pdf", PdfRedline.Rendered);
Console.WriteLine("Wrote redline.pdf");
```

```text
Wrote redline.pdf
```

## Related recipes

- [Combine document reviewer changes](https://recursiveai.org/onediff/cookbook/combine-reviewer-changes/)
- [Three-way text merge](https://recursiveai.org/onediff/cookbook/three-way-text-merge/)

## The short answer

Register `PdfRedline`, then call `Redline.Create(oldPath, newPath, outputPath)`. With a PDF output path, OneDiff writes markup annotations on the new document’s own pages. Changed text is highlighted and replacements carry old text in pop-ups. The snippet at the top writes a real annotated PDF, not a screenshot or a pixel-difference image.

The [PDF documentation](https://recursiveai.org/onediff/docs/pdf/) distinguishes original-page markup from a rendered redline. Choose original-page markup when the reviewer needs to see changes in the existing page layout. Choose rendered output when a newly laid-out comparison is more useful than annotations.

## Can you compare two PDFs and highlight differences?

Yes, for text-bearing PDFs. OneDiff reads the text out of each PDF and compares it. It aligns the versions and places annotations at the changed text’s positions on the new pages.

Inserted text receives a highlight. Replacements are highlighted with the previous text in a pop-up. Deleted text cannot be highlighted on a new page where it no longer exists, so a caret marks its position and the pop-up carries the deleted text. Formatting changes use underlines, while moves have their own annotations. A review UI should not treat every mark as a simple insertion.

The PDF’s page content is not rewritten by original-page markup. The annotation layer carries the comparison. A viewer that hides annotations can therefore make the output look unchanged. Open the comments or annotation display when reviewing the file. The printed “Wrote markup.pdf” line confirms the save completed; the visible marks are in the PDF, not in console output.

## How can I compare the differences between two PDF files?

Decide first what “difference” means for your application. This package compares extracted document text, structure and supported formatting. It is not a pixel comparison of rendered pages. The model does not include images, vector graphics, existing annotations, form fields or document properties, according to the PDF reader documentation.

A changed logo, an edited diagram or a different form value is therefore not covered just because the page opens successfully. Use this task for document text review, not as evidence that two files are visually identical or contain identical binary objects.

Text extraction also reconstructs paragraphs and reading order. Line wrapping inside a paragraph can be folded into spaces, and common document comparison settings can suppress selected presentation differences. This is useful when a sentence reflows between versions, but it means the result is not a literal byte-by-byte report. Keep the original inputs when the review must preserve the source evidence.

## How do you highlight changes on the original PDF pages?

Use the default original-page form shown at the top. For a comparison you have already computed, the original-page writer checks that the source PDF bytes match those read for the comparison. It cannot safely place anchors onto a different revision that happens to have the same filename.

The variation writes `redline.pdf` with `PdfRedline.Rendered`. That creates a rendered, tagged redline rather than marking the original layout. It is a separate output choice, not another spelling of the same operation. Decide which form to send based on whether the recipient needs the original page context or a reflowed comparison.

## Can you compare scanned PDF files?

Not through the text-only path shown here. A scan without a usable text layer is refused with a message naming the OCR package, rather than being mistaken for an empty document. The documented scan path uses `RecursiveAI.OneDiff.Ocr` and `OcrRedline.Register()`; OCR introduces recognition uncertainty and is a different input path.

A damaged file is not necessarily a scan. The reader distinguishes malformed content, encryption problems and size limits from missing text. Resolve the reported input problem rather than adding OCR to every failure. For supported digital documents, keep this page’s smaller text-bearing workflow.
