{"id":10659,"library":"concordance","title":"Concordance JavaScript Value Utility","description":"Concordance is a robust JavaScript utility library designed for deep comparison, human-readable formatting, detailed diffing, and consistent serialization of any JavaScript value. Currently stable at version 5.0.4, it maintains an active release cadence with frequent patch releases addressing minor issues and less frequent major versions that introduce breaking changes or significant feature enhancements. A key differentiator is its consistent underlying algorithm applied across all core operations—comparison, formatting, and diffing—ensuring predictable behavior. It offers granular control over comparisons, notably treating `-0` as distinct from `0`, `NaN` as equal to `NaN`, and comparing functions, promises, and symbols strictly by identity. Formatting is optimized for legibility, including special handling for multi-line strings and control characters. Concordance also supports serialization for later comparison, with specific behavioral changes noted when a deserialized value is used as the 'actual' value in comparisons.","status":"active","version":"5.0.4","language":"javascript","source_language":"en","source_url":"https://github.com/concordancejs/concordance","tags":["javascript"],"install":[{"cmd":"npm install concordance","lang":"bash","label":"npm"},{"cmd":"yarn add concordance","lang":"bash","label":"yarn"},{"cmd":"pnpm add concordance","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Concordance v5+ is primarily designed for ES Modules. While CommonJS `require` might work in some setups, named ES imports are the recommended approach.","wrong":"const compare = require('concordance').compare","symbol":"compare","correct":"import { compare } from 'concordance'"},{"note":"Concordance does not provide a default export; all primary utilities like `format` are exposed as named exports.","wrong":"import concordance from 'concordance'; const formatted = concordance.format(value)","symbol":"format","correct":"import { format } from 'concordance'"},{"note":"The `serialize` and `deserialize` functions are designed to be used in tandem for persisting and re-hydrating values, especially for later comparisons.","symbol":"serialize","correct":"import { serialize, deserialize } from 'concordance'"}],"quickstart":{"code":"import { diff, format } from 'concordance';\n\ninterface User {\n  id: number;\n  name: string;\n  email?: string;\n  address: {\n    street: string;\n    city: string;\n    zip: string;\n  };\n  roles: string[];\n  createdAt: Date;\n  lastLogin?: Date;\n  preferences?: Map<string, any>;\n}\n\nconst user1: User = {\n  id: 1,\n  name: 'Alice',\n  email: 'alice@example.com',\n  address: {\n    street: '123 Main St',\n    city: 'Anytown',\n    zip: '12345'\n  },\n  roles: ['admin', 'editor'],\n  createdAt: new Date('2023-01-01T10:00:00Z'),\n  preferences: new Map([['theme', 'dark'], ['notifications', true]])\n};\n\nconst user2: User = {\n  id: 1,\n  name: 'Alicia', // Changed name\n  // email missing\n  address: {\n    street: '123 Main Street', // Street name changed slightly\n    city: 'Anytown',\n    zip: '12345'\n  },\n  roles: ['editor'], // Role removed\n  createdAt: new Date('2023-01-01T10:00:00Z'),\n  lastLogin: new Date('2024-04-18T15:30:00Z') // New field\n};\n\nconsole.log(\"--- Diffing two user objects ---\");\nconst userDiff = diff(user1, user2);\nconsole.log(format(userDiff));\n\nconst objA = { a: 1, b: { c: 2 } };\nconst objB = { a: 1, b: { c: 3, d: 4 } };\nconsole.log(\"\\n--- Diffing simple objects ---\");\nconsole.log(format(diff(objA, objB)));\n\n// Example of how -0 and 0 are handled distinctly\nconsole.log(\"\\n--- Comparing -0 and 0 ---\");\nconst negativeZeroDiff = diff(-0, 0);\nconsole.log(format(negativeZeroDiff)); // Will show a difference","lang":"typescript","description":"This quickstart demonstrates how to use `diff` to compare two complex JavaScript objects and `format` to render the differences in a human-readable way. It also includes an example highlighting Concordance's unique handling of `-0` versus `0`."},"warnings":[{"fix":"Review existing comparison logic, especially for tests involving circular data structures, to ensure the new behavior aligns with expectations and update any assertions if needed.","message":"Concordance v3.0.0 introduced a breaking change to how circular references are compared. Previously, all circular references were considered unequal. As of v3.0.0, if the *same* cycle is present in both the actual and expected values, they are considered equal; otherwise, they are unequal.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Upgrade your Node.js environment to version 6 or higher to use Concordance v4.x, or Node.js 10 or higher for v5.x and beyond.","message":"Concordance v4.0.0 dropped support for Node.js 4. Users running Node.js environments older than version 6 must upgrade their Node.js runtime to use Concordance v4.x or later.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Ensure your Node.js environment is version 10 or higher. For continuous integration setups, verify and update the Node.js version specified in your `package.json` `engines` field and CI configuration.","message":"Concordance v5.0.0 and subsequent versions explicitly require Node.js 10 or higher. Running on older Node.js versions (e.g., Node.js 8) will result in errors.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Always pass the deserialized value as the *actual* value to comparison and diffing methods. Be aware that comparisons involving deserialized values may not behave identically to comparisons between original, live JavaScript values for certain types.","message":"When comparing deserialized values, specific behaviors change compared to live JavaScript values. For example, `Argument` values can only be compared to other `Argument` values, `Function` values are compared by name, `Promise` values by their constructor and enumerable properties (not identity), and `Symbol` values by their string serialization.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"When performing comparisons or writing assertions, ensure your test expectations account for Concordance's specific handling of `-0` and `NaN`.","message":"Concordance's comparison logic treats `-0` as distinct from `0`, and `NaN` as equal to `NaN`. This behavior deviates from standard JavaScript strict equality (`===`) for both `-0` and `NaN`.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Switch to ES module import syntax: `import { compare } from 'concordance';`","cause":"Attempting to use CommonJS `require()` syntax (e.g., `const { compare } = require('concordance');`) in an ES module environment, such as a `.mjs` file or a project with `\"type\": \"module\"` in `package.json`.","error":"ReferenceError: require is not defined in ES module scope"},{"fix":"Use named imports for ES Modules: `import { compare } from 'concordance';`. If in a CommonJS context, ensure correct destructuring: `const { compare } = require('concordance');`.","cause":"This error typically occurs when trying to access `compare` as a property of a non-existent default import, or when `require('concordance')` does not return an object with `compare` as a direct property in a CommonJS context.","error":"TypeError: concordance.compare is not a function"},{"fix":"If your project is CommonJS, use `const { format } = require('concordance');`. If you intend to use ES Modules, ensure your `package.json` includes `\"type\": \"module\"` or rename your file to `.mjs`.","cause":"Using `import` syntax (e.g., `import { format } from 'concordance';`) in a CommonJS file, which is the default for `.js` files unless `\"type\": \"module\"` is set in `package.json` or the file has a `.mjs` extension.","error":"SyntaxError: Cannot use import statement outside a module"}],"ecosystem":"npm"}