Visual Variable Diff
variable-diff is a JavaScript/TypeScript library designed to generate a visual diff between two JavaScript variables, primarily objects or JSON structures. It focuses on presenting only the differences (additions, deletions, and modifications) in a human-readable, formatted output, making it easier to identify changes without sifting through identical data. The current stable version is 2.0.2. While there isn't an explicit release cadence, the project appears to be actively maintained, with recent updates introducing new features like an options argument in version 2.0.1. Its key differentiator is its emphasis on clear, colored, and indented output directly within the console or logs, making it particularly useful for debugging and comparing configuration objects or data states efficiently.
Common errors
-
TypeError: diff is not a function
cause This error commonly occurs when `variable-diff` is imported incorrectly. In CommonJS, trying `require('variable-diff').diff` or in ESM, using `import { diff } from 'variable-diff';` will cause this because `diff` is a default export.fixCorrect the import statement: for CommonJS, use `const diff = require('variable-diff');`; for ES Modules, use `import diff from 'variable-diff';`. -
ReferenceError: chalk is not defined
cause If you copy the `wrap` function example from the library's `defaultOptions` snippet (which implicitly uses the `chalk` library for coloring) into your options without having `chalk` installed in your project, this error will occur.fixTo resolve, either install `chalk` as a dependency (`npm install chalk`) if you intend to use its coloring features, or remove the `wrap` function from your options to let `variable-diff` use its default color handling (or no colors if `color: false` is set).
Warnings
- gotcha When `color: true` (the default) or a custom `wrap` function (e.g., using `chalk`) is utilized, the output relies on ANSI escape codes for coloring. These codes may not render correctly in all environments, potentially showing raw escape sequences instead of colors (e.g., some non-TTY output streams or basic text editors).
- gotcha For ES Module environments, `variable-diff` uses a default export for its primary `diff` function. Incorrectly attempting a named import (`import { diff } from 'variable-diff';`) will lead to `diff` being `undefined`.
- gotcha Comparing objects with circular references (where an object directly or indirectly references itself) might lead to infinite loops or unexpected behavior, as the library's diffing algorithm may not inherently detect and handle all such cases gracefully.
Install
-
npm install variable-diff -
yarn add variable-diff -
pnpm add variable-diff
Imports
- diff
import { diff } from 'variable-diff';import diff from 'variable-diff';
- diff (CommonJS)
const diff = require('variable-diff'); - DiffOptions (Type)
import type { DiffOptions } from 'variable-diff';
Quickstart
import diff from 'variable-diff';
interface UserProfile {
id: string;
name: string;
email: string;
preferences?: {
theme: 'dark' | 'light';
notifications: boolean;
language: string;
};
roles: string[];
}
const oldProfile: UserProfile = {
id: 'user_123',
name: 'Alice Smith',
email: 'alice@example.com',
preferences: {
theme: 'dark',
notifications: true,
language: 'en-US'
},
roles: ['user', 'editor']
};
const newProfile: UserProfile = {
id: 'user_123',
name: 'Alice Johnson',
email: 'alice.johnson@example.com',
preferences: {
theme: 'light',
notifications: false,
language: 'en-GB'
},
roles: ['user', 'admin']
};
const diffOptions = {
indent: ' ', // 2 spaces for indentation
newLine: '\n', // Newline character
color: true // Enable colored output, set to false for plain text
};
console.log('--- Profile Changes ---\n');
const result = diff(oldProfile, newProfile, diffOptions);
console.log(result.text);
if (result.changed) {
console.log('\nDetected changes in profile data.');
} else {
console.log('\nNo changes detected in profile data.');
}
// Accessing programmatic changes (raw object)
// console.log('\nRaw changes object:', JSON.stringify(result.changes, null, 2));