Unified Diff Parser
parse-diff is a lightweight and focused JavaScript library designed to parse unified diff format strings, typically generated by version control systems like Git. It transforms a raw diff string into a structured JavaScript array of file objects, each containing chunks of changes and individual line modifications, including metadata like additions, deletions, and file paths. The current stable version is 0.12.0, published in January 2023, indicating a mature and stable project with an infrequent release cadence. While other parsers exist (e.g., `diffparser`, `parse-git-diff`), `parse-diff` is known for its simplicity and direct approach to the unified diff format, making it suitable for applications requiring programmatic access to diff data. It ships with TypeScript types, enhancing developer experience for TypeScript projects.
Common errors
-
TypeError: parse is not a function
cause Attempting to import `parse` as a named export (`import { parse } from 'parse-diff'`) in an ESM module or TypeScript, or destructuring `require('parse-diff')` in CommonJS. The `parse` function is the module's default export.fixFor ESM/TypeScript, use `import parse from 'parse-diff';`. For CommonJS, use `const parse = require('parse-diff');`. -
Error: [ERR_REQUIRE_ESM]: require() of ES Module ... not supported. Instead change the require of ... to a dynamic import() ...
cause Using `require('parse-diff')` in a CommonJS module while `parse-diff` might have been resolved to an ESM-only version or an environment configured for ESM. While `parse-diff` supports CJS, conflicts can arise in mixed environments.fixIf encountering this error, ensure your project's module resolution is consistent. If your project is primarily CommonJS, verify `parse-diff` is installed in a compatible version. If you are in an ESM context, always use `import parse from 'parse-diff';`. -
The parsed output array is empty or contains fewer files/chunks than expected, despite valid diff input.
cause Subtle formatting issues in the input diff string (e.g., incorrect line endings, malformed headers, non-standard Git extensions) can cause the parser to fail silently or misinterpret sections, resulting in incomplete or empty output.fixDouble-check the input diff for strict adherence to the unified diff format. Use a reliable source for diff strings (e.g., `git diff`). Consider adding pre-parsing validation or sanitization steps for user-provided diffs.
Warnings
- breaking As a 0.x.x version, `parse-diff` adheres to a relaxed Semantic Versioning where minor versions (e.g., 0.11.0 to 0.12.0) *can* introduce breaking changes to the API or the structure of the parsed output. Always review release notes when updating.
- gotcha The parser expects input in a strict unified diff format. Malformed or non-standard diff strings may lead to unexpected results, such as empty arrays being returned or incomplete parsing, rather than explicit errors.
- gotcha For very large diff files (e.g., hundreds of thousands of lines), parsing can be memory-intensive due to the entire diff string being loaded into memory and the resulting object structure. This can lead to performance bottlenecks or out-of-memory errors in resource-constrained environments.
Install
-
npm install parse-diff -
yarn add parse-diff -
pnpm add parse-diff
Imports
- parse
import { parse } from 'parse-diff';import parse from 'parse-diff';
- parse
const { parse } = require('parse-diff');const parse = require('parse-diff'); - File structure types
import type { File, Chunk, Change } from 'parse-diff';
Quickstart
import parse from 'parse-diff';
const diffString = `diff --git a/README.md b/README.md
index c96dc36..0e564d2 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
# parse-diff
Simple unified diff parser for JavaScript
-## JavaScript Usage Example
+## Usage Example
+
`;
const files = parse(diffString);
console.log(`Number of patched files: ${files.length}`);
files.forEach(file => {
console.log(`\nFile: ${file.from} -> ${file.to}`);
console.log(` Additions: ${file.additions}, Deletions: ${file.deletions}`);
file.chunks.forEach(chunk => {
console.log(` Chunk content: ${chunk.content}`);
chunk.changes.forEach(change => {
console.log(` Line (${change.type}): ${change.content}`);
});
});
});