Package Exports
- json-conflict-resolver
Readme
Git Json Resolver 
A Git-aware conflict resolver for JSON-first structured data.
Why?
- Git merge conflicts in structured files (JSON, YAML, XML, TOML) are painful.
- Manual resolution is error-prone, time-consuming, and breaks CI/CD pipelines.
git-json-resolverautomates conflict handling with configurable strategies.- Non-JSON formats are internally normalized to JSON → resolved → converted back.
Features
- ⚡ Primary focus on JSON (first-class support)
- 🔄 YAML, XML, TOML supported via conversion
- 🧩 Rule-based strategies (per path/pattern)
- 🗂️ Handles small configs to huge repos (optimizations built-in)
- 🔌 Pluggable matcher abstraction (picomatch, micromatch supported out of the box with peerDependency)
- 🛠️ Configurable trade-offs for speed vs. memory
- 🗃️ Planned: extend configuration to use different strategies per file (ideas and edge cases welcome!)
Installation
pnpm add git-json-resolveror
npm install git-json-resolveror
yarn add git-json-resolverQuick Start
Add a custom merge driver to your Git config:
git config merge.json-resolver.name "Custom JSON merge driver"
git config merge.json-resolver.driver "npx git-json-resolver %A %O %B"Update .gitattributes to use it for JSON files:
*.json merge=json-resolverExample Config
import { resolveConflicts } from "git-json-resolver";
const result = resolveConflicts({
filePath: "package.json",
rules: [
{ pattern: "dependencies.*", strategy: "ours" },
{ pattern: "version", strategy: "theirs", important: true },
{ pattern: "scripts.build", strategy: "manual" },
],
matcher: "picomatch", // default
optimize: {
cacheMatchers: true,
streamMode: false, // set true for very large repos
},
});Upcoming: File-Specific Strategies
We are exploring the ability to define per-file strategy sets in config, e.g.:
rulesByFile: {
"package.json": { version: ["theirs"], dependencies: ["ours"] },
"*.config.json": { "*": ["merge"] },
},This raises interesting questions/edge cases:
- How to merge file-level vs. global rules?
- Should
include/excludestill apply if a file is explicitly listed? - Should conflicting rules between file + global fall back to default strategy or error?
We welcome ideas & edge cases here!
Supported Strategies
- ours → take current branch value
- theirs → take incoming branch value
- manual → mark for human resolution
- drop → remove the key entirely
- custom → user-defined resolver function
Supported Formats
- JSON (native)
- YAML, XML, TOML → converted to JSON → resolved → converted back
Performance & Optimization
- Matcher caching for repeated patterns
- Streaming mode for very large repos (low memory footprint)
- Trade-offs are configurable via
optimizefield
Roadmap
- Richer strategies via plugins (e.g., semantic version resolver)
- CLI UX improvements
- Pluggable format converters customizations
- VSCode integration for previewing merge resolutions
- Per-file strategies support (current RFC)
Contributing
Contributions welcome 🙌
- Fork, branch, PR — with tests (
vitestrequired) - Docs live in
libDocs/(tutorials, guides, deep dives) - API reference generated into
docs/via TypeDoc
License
This library is licensed under the MPL-2.0 open-source license.
Please enroll in our courses or sponsor our work.
with 💖 by Mayank Kumar Chaudhari