Diff utility

diffUtility

Compares two documents and returns a list of changes between them.

Supported formats

The Diff Utility can be used to compare entire documents or parts of them.

To compare entire documents, you can provide them in Tiptap JSON format or as a ProseMirror Node.

To compare parts of the document, you can provide them as a Tiptap JSON fragment (a list of Tiptap JSON nodes) or as a ProseMirror Fragment.

Parameters (DiffUtilityOptions)

  • schema (Schema): The ProseMirror schema used in the editor. Can be obtained from the editor instance: editor.schema
  • docA (Node | Fragment | JSONContent | JSONContent[]): Original document. Can be a ProseMirror Node/Fragment or Tiptap JSON
  • docB (Node | Fragment | JSONContent | JSONContent[]): Modified document. Can be a ProseMirror Node/Fragment or Tiptap JSON
  • simplifyChanges? (boolean): Whether to simplify the changes so that if there are multiple changes in the same word, they are merged into one change. Does not apply when mode is 'block'. Default: true
  • ignoreAttributes? (string[]): The attributes to ignore. Default: ['id', 'data-thread-id']
  • ignoreMarks? (string[]): The marks to ignore. Default: ['inlineThread']
  • changeMergeDistance? (number | null): Minimum length for an unchanged range to be considered significant. Unchanged ranges shorter than this value will be absorbed into adjacent changes, merging them into a single change. Set to null or undefined to use the auto-calculated default. Does not apply when mode is 'block'. Default: 10
  • groupInlineChanges? (number): Controls when inline edits are grouped into one block-level change in smart mode. Use 1 (default) to group only when all inline content changed, 0 to always group, and 2 to never group.
  • mode? ('smart' | 'inline' | 'block'): The diff mode to use for comparison.
    • 'smart' (default) balances block-level and inline-level output for readable review suggestions.
    • 'inline' performs character-level diff that identifies precise changes within text.
    • 'block' performs block-level diff that treats each top-level node as a single unit. In block mode, simplifyChanges and changeMergeDistance are ignored.

In the playground below, click on the "Show diff options" button and see how each option affects the diff:

Returns (Change[])

Returns a list of changes. Each Change item contains:

  • rangeA (Range): The range in the original document that has changed
  • rangeB (Range): The range in the modified document that has changed

Example

import { diffUtility } from '@tiptap-pro/ai-toolkit'

// Compute changes between two documents (uses 'smart' mode by default)
const changes = diffUtility({
  schema: editor.schema,
  docA,
  docB,
})

// Use block-level diffing
const blockChanges = diffUtility({
  schema: editor.schema,
  docA,
  docB,
  mode: 'block',
})

// Use inline (character-level) diffing
const inlineChanges = diffUtility({
  schema: editor.schema,
  docA,
  docB,
  mode: 'inline',
})

Compare documents in real-time

Compare two documents in real-time and show the diff in the editor.

Works in non-AI use cases

This feature does not need AI to work. It can compare any two documents, regardless of whether they are AI-generated or not.

For a step-by-step guide on comparing documents, see the Compare documents guide.

startComparingDocuments

Starts real-time comparison with another document. Differences are displayed as suggestions in an inline diff view where the old and the new content are displayed in the editor.

Parameters (StartComparingDocumentsOptions)

  • otherDoc? (Node): The document to compare against. It is a ProseMirror Node object. Defaults to a snapshot of the current document if omitted
  • displayOptions? (DisplayOptions): Controls how differences are rendered as suggestions. See available options.
  • debounceTimeout? (number): Milliseconds to wait before recomputing diffs. A low value will make the app seem more responsive, but it might cause performance issues in large documents. Default: 500
  • diffUtilityOptions? (ExternalDiffUtilityOptions): Options for comparing the documents with the diff utility. See available options.

Returns

void

Example

// Start comparing changes with another document
toolkit.startComparingDocuments({
  otherDoc,
})

stopComparingDocuments

Stops the real-time comparison and clears all suggestions, so the diff view is no longer visible.

Returns

void

Example

// Stop comparison and clear decorations
toolkit.stopComparingDocuments()

Accepting and rejecting changes

When comparing documents, changes are displayed as suggestions. To accept or reject individual changes or all changes at once, use the suggestion methods:

See the Compare documents guide for a usage example.