or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-operations.mddiffpatcher-class.mdformatters.mdindex.mdoptions-configuration.md
tile.json

index.mddocs/

0

# jsondiffpatch

1

2

jsondiffpatch is a comprehensive JSON diff & patch library that detects differences between JavaScript objects and arrays, generates change deltas, and applies patches to transform objects from one state to another. It supports intelligent array diffing using LCS algorithm, multiple output formats, text diffing for strings, and extensive customization options.

3

4

## Package Information

5

6

- **Package Name**: jsondiffpatch

7

- **Package Type**: npm

8

- **Language**: TypeScript/JavaScript

9

- **Installation**: `npm install jsondiffpatch`

10

11

## Core Imports

12

13

```javascript

14

import { create, diff, patch, unpatch, reverse, clone, DiffPatcher } from "jsondiffpatch";

15

```

16

17

For text diff support:

18

19

```javascript

20

import { create, diff, patch, unpatch, reverse, clone, DiffPatcher } from "jsondiffpatch/with-text-diffs";

21

```

22

23

CommonJS:

24

25

```javascript

26

const { create, diff, patch, unpatch, reverse, clone, DiffPatcher } = require("jsondiffpatch");

27

```

28

29

## Basic Usage

30

31

```javascript

32

import { diff, patch, reverse } from "jsondiffpatch";

33

34

// Generate diff between two objects

35

const left = { name: "Alice", age: 25, active: true };

36

const right = { name: "Alice", age: 26, active: false, role: "admin" };

37

38

const delta = diff(left, right);

39

console.log(delta);

40

// { age: [25, 26], active: [true, false], role: ["admin"] }

41

42

// Apply patch to get target object

43

const result = patch(left, delta);

44

console.log(result);

45

// { name: "Alice", age: 26, active: false, role: "admin" }

46

47

// Reverse a patch

48

const reverseDelta = reverse(delta);

49

const original = patch(result, reverseDelta);

50

console.log(original);

51

// { name: "Alice", age: 25, active: true }

52

```

53

54

## Architecture

55

56

jsondiffpatch is built around several key components:

57

58

- **DiffPatcher Class**: Main class providing diff, patch, reverse, and utility operations

59

- **Processing Pipeline**: Filter-based architecture using pipes for extensible diff/patch operations

60

- **Context System**: Specialized contexts (DiffContext, PatchContext, ReverseContext) for each operation type

61

- **Delta Types**: Structured representation of changes (added, modified, deleted, moved, text diffs)

62

- **Formatters**: Multiple output formats including console, HTML, JSON Patch, and annotated formats

63

- **Filter System**: Modular filters for handling arrays, objects, text, dates, and trivial cases

64

65

## Capabilities

66

67

### Core Operations

68

69

Primary diff and patch operations for generating and applying changes between JavaScript values.

70

71

```javascript { .api }

72

function diff(left: unknown, right: unknown): Delta;

73

function patch(left: unknown, delta: Delta): unknown;

74

function unpatch(right: unknown, delta: Delta): unknown;

75

function reverse(delta: Delta): Delta;

76

function clone(value: unknown): unknown;

77

function create(options?: Options): DiffPatcher;

78

```

79

80

[Core Operations](./core-operations.md)

81

82

### DiffPatcher Class

83

84

Object-oriented interface providing full control over diff and patch operations with customizable options.

85

86

```javascript { .api }

87

class DiffPatcher {

88

constructor(options?: Options);

89

diff(left: unknown, right: unknown): Delta;

90

patch(left: unknown, delta: Delta): unknown;

91

unpatch(right: unknown, delta: Delta): unknown;

92

reverse(delta: Delta): Delta;

93

clone(value: unknown): unknown;

94

options(options?: Options): Options;

95

}

96

```

97

98

[DiffPatcher Class](./diffpatcher-class.md)

99

100

### Formatters

101

102

Multiple output formats for visualizing and processing diffs including console output, HTML visualization, JSON Patch compatibility, and annotated formatting.

103

104

```javascript { .api }

105

// Console formatter

106

import * as console from "jsondiffpatch/formatters/console";

107

function format(delta: Delta, left?: unknown): string;

108

function log(delta: Delta, left?: unknown): void;

109

110

// HTML formatter

111

import * as html from "jsondiffpatch/formatters/html";

112

function format(delta: Delta, left?: unknown): string;

113

function showUnchanged(show?: boolean, node?: Element, delay?: number): void;

114

function hideUnchanged(node?: Element, delay?: number): void;

115

116

// JSON Patch formatter

117

import * as jsonpatch from "jsondiffpatch/formatters/jsonpatch";

118

function format(delta: Delta): Op[];

119

function patch(target: unknown, operations: Op[]): void;

120

121

// Annotated formatter

122

import * as annotated from "jsondiffpatch/formatters/annotated";

123

function format(delta: Delta, left?: unknown): string;

124

```

125

126

[Formatters](./formatters.md)

127

128

### Options and Configuration

129

130

Comprehensive configuration system for customizing diff behavior including array handling, text diffing, property filtering, and output formatting.

131

132

```javascript { .api }

133

interface Options {

134

objectHash?: (item: object, index?: number) => string | undefined;

135

matchByPosition?: boolean;

136

arrays?: {

137

detectMove?: boolean;

138

includeValueOnMove?: boolean;

139

};

140

textDiff?: {

141

diffMatchPatch: typeof diff_match_patch;

142

minLength?: number;

143

};

144

propertyFilter?: (name: string, context: DiffContext) => boolean;

145

cloneDiffValues?: boolean | ((value: unknown) => unknown);

146

omitRemovedValues?: boolean;

147

}

148

```

149

150

[Options and Configuration](./options-configuration.md)

151

152

## Delta Types

153

154

jsondiffpatch uses structured delta objects to represent different types of changes:

155

156

```javascript { .api }

157

type Delta = AddedDelta | ModifiedDelta | DeletedDelta | ObjectDelta | ArrayDelta | MovedDelta | TextDiffDelta | undefined;

158

159

// Basic change types

160

type AddedDelta = [unknown]; // [newValue]

161

type ModifiedDelta = [unknown, unknown]; // [oldValue, newValue]

162

type DeletedDelta = [unknown, 0, 0]; // [oldValue, 0, 0]

163

164

// Complex change types

165

type MovedDelta = [unknown, number, 3]; // [value, newIndex, 3]

166

type TextDiffDelta = [string, 0, 2]; // [diffString, 0, 2]

167

interface ObjectDelta { [property: string]: Delta; }

168

interface ArrayDelta { _t: "a"; [index: number | `${number}`]: Delta; }

169

```

170

171

### Type Guards

172

173

```javascript { .api }

174

function isAddedDelta(delta: Delta): delta is AddedDelta;

175

function isModifiedDelta(delta: Delta): delta is ModifiedDelta;

176

function isDeletedDelta(delta: Delta): delta is DeletedDelta;

177

function isObjectDelta(delta: Delta): delta is ObjectDelta;

178

function isArrayDelta(delta: Delta): delta is ArrayDelta;

179

function isMovedDelta(delta: Delta): delta is MovedDelta;

180

function isTextDiffDelta(delta: Delta): delta is TextDiffDelta;

181

```

182

183

## Context Types

184

185

Context objects provide state and configuration for diff, patch, and reverse operations. These are primarily used when creating custom filters or advanced pipeline customization.

186

187

```javascript { .api }

188

// Base context class

189

abstract class Context<TResult> {

190

abstract pipe: string;

191

result?: TResult;

192

hasResult?: boolean;

193

exiting?: boolean;

194

parent?: Context<TResult>;

195

childName?: string | number;

196

root?: Context<TResult>;

197

options?: Options;

198

children?: Context<TResult>[];

199

nextAfterChildren?: Context<TResult> | null;

200

next?: Context<TResult> | null;

201

202

setResult(result: TResult): this;

203

exit(): this;

204

push(child: Context<TResult>, name?: string | number): this;

205

}

206

207

// Diff operation context

208

class DiffContext extends Context<Delta> {

209

pipe: "diff";

210

left: unknown;

211

right: unknown;

212

leftType?: string;

213

rightType?: string;

214

leftIsArray?: boolean;

215

rightIsArray?: boolean;

216

217

constructor(left: unknown, right: unknown);

218

prepareDeltaResult<T extends Delta>(result: T): T;

219

setResult(result: Delta): this;

220

}

221

222

// Patch operation context

223

class PatchContext extends Context<unknown> {

224

pipe: "patch";

225

left: unknown;

226

delta: Delta;

227

228

constructor(left: unknown, delta: Delta);

229

}

230

231

// Reverse operation context

232

class ReverseContext extends Context<Delta> {

233

pipe: "reverse";

234

delta: Delta;

235

236

constructor(delta: Delta);

237

}

238

```

239

240

**Usage in Custom Filters:**

241

242

```javascript

243

import { DiffContext, PatchContext, ReverseContext } from "jsondiffpatch";

244

245

// Example custom filter

246

const customFilter = (context) => {

247

if (context.pipe === "diff") {

248

const diffCtx = context; // DiffContext

249

console.log(`Diffing: ${typeof diffCtx.left} -> ${typeof diffCtx.right}`);

250

251

// Access parent context for nested operations

252

if (diffCtx.parent) {

253

console.log(`Parent operation: ${diffCtx.parent.pipe}`);

254

}

255

256

// Set custom result

257

if (diffCtx.left === diffCtx.right) {

258

diffCtx.setResult(undefined); // No difference

259

diffCtx.exit(); // Skip further processing

260

}

261

}

262

};

263

264

// Context hierarchy for nested objects

265

const result = diff({ user: { name: "Alice" } }, { user: { name: "Bob" } });

266

// Creates nested DiffContext instances:

267

// - Root context for entire object

268

// - Child context for 'user' property

269

// - Child context for 'name' property

270

```

271

272

## Utilities

273

274

```javascript { .api }

275

/**

276

* JSON.parse reviver function for converting ISO date strings back to Date objects

277

* Handles ISO 8601 format: YYYY-MM-DDTHH:mm:ss.sssZ or YYYY-MM-DDTHH:mm:ss±HH:mm

278

* @param key - Property key (unused)

279

* @param value - Property value to potentially revive

280

* @returns Date object if value matches ISO date pattern, otherwise original value

281

*/

282

function dateReviver(key: string, value: unknown): unknown;

283

284

/**

285

* Create deep clone of any value using the default DiffPatcher instance

286

* @param value - Value to clone

287

* @returns Deep cloned copy

288

*/

289

function clone(value: unknown): unknown;

290

```

291

292

**Date Reviver Usage:**

293

294

```javascript

295

import { dateReviver } from "jsondiffpatch";

296

297

// Parse JSON with automatic date revival

298

const jsonString = '{"created": "2023-12-25T10:30:00.000Z", "name": "example"}';

299

const parsed = JSON.parse(jsonString, dateReviver);

300

301

console.log(parsed.created instanceof Date); // true

302

console.log(parsed.created.getFullYear()); // 2023

303

console.log(parsed.name); // "example" (unchanged)

304

305

// Handles various ISO 8601 formats

306

const formats = [

307

"2023-12-25T10:30:00Z", // UTC

308

"2023-12-25T10:30:00.123Z", // UTC with milliseconds

309

"2023-12-25T10:30:00+05:30", // Timezone offset

310

"2023-12-25T10:30:00-08:00" // Negative timezone

311

];

312

313

formats.forEach(dateStr => {

314

const result = dateReviver("", dateStr);

315

console.log(result instanceof Date); // true for all

316

});

317

```

318

319

## CLI Tool

320

321

jsondiffpatch includes a command-line interface for diffing JSON files with support for HTTP URLs and multiple output formats:

322

323

```bash

324

jsondiffpatch left.json right.json [options]

325

```

326

327

**Options:**

328

329

- `--format=console|json|json-compact|jsonpatch` - Output format (default: console)

330

- `--omit-removed-values` - Exclude removed values from output (makes diffs irreversible)

331

- `--no-moves` - Disable array move detection (improves performance on large arrays)

332

- `--no-text-diff` - Disable text diffing for long strings

333

- `--object-keys=prop1,prop2` - Object matching keys for arrays (default: id,key)

334

- `--help` - Show usage information with example output

335

336

**Exit Codes:**

337

338

- `0` - No differences found between files

339

- `1` - Differences found (standard for diff tools)

340

- `2` - Error occurred (invalid arguments, file not found, etc.)

341

342

**Input Sources:**

343

344

- Local JSON files: `file1.json file2.json`

345

- HTTP/HTTPS URLs: Automatically fetches and parses JSON from URLs

346

- Mixed sources: `local.json https://api.example.com/data`

347

348

**Usage Examples:**

349

350

```bash

351

# Basic diff with colorized console output

352

jsondiffpatch file1.json file2.json

353

354

# Raw JSON delta output

355

jsondiffpatch file1.json file2.json --format=json

356

357

# Compact JSON (single line)

358

jsondiffpatch file1.json file2.json --format=json-compact

359

360

# RFC 6902 JSON Patch format

361

jsondiffpatch file1.json file2.json --format=jsonpatch

362

363

# Disable move detection for performance

364

jsondiffpatch large1.json large2.json --no-moves

365

366

# Compare remote APIs

367

jsondiffpatch https://api.example.com/v1 https://api.example.com/v2

368

369

# Object matching by specific keys (for array elements)

370

jsondiffpatch users1.json users2.json --object-keys=id,email

371

372

# Omit old values (smaller output, cannot reverse)

373

jsondiffpatch old.json new.json --omit-removed-values

374

375

# Help with live demo

376

jsondiffpatch --help

377

```

378

379

**Default Behavior:**

380

381

- Uses text diffing by default (via `jsondiffpatch/with-text-diffs`)

382

- Array objects matched by `id` or `key` properties first, then by position

383

- Move detection enabled for arrays

384

- Console output with ANSI colors for terminal display