{"id":51118994,"url":"https://github.com/sulthonzh/configdiff","last_synced_at":"2026-06-25T00:30:36.025Z","repository":{"id":365790846,"uuid":"1267232620","full_name":"sulthonzh/configdiff","owner":"sulthonzh","description":"Semantic diff for config files — JSON, YAML, TOML","archived":false,"fork":false,"pushed_at":"2026-06-18T21:53:15.000Z","size":14,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-18T23:22:23.415Z","etag":null,"topics":["compare","config","diff","json","semantic","toml","yaml"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sulthonzh.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-12T10:50:12.000Z","updated_at":"2026-06-18T21:53:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sulthonzh/configdiff","commit_stats":null,"previous_names":["sulthonzh/configdiff"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/sulthonzh/configdiff","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sulthonzh%2Fconfigdiff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sulthonzh%2Fconfigdiff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sulthonzh%2Fconfigdiff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sulthonzh%2Fconfigdiff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sulthonzh","download_url":"https://codeload.github.com/sulthonzh/configdiff/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sulthonzh%2Fconfigdiff/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34755061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compare","config","diff","json","semantic","toml","yaml"],"created_at":"2026-06-25T00:30:35.915Z","updated_at":"2026-06-25T00:30:36.019Z","avatar_url":"https://github.com/sulthonzh.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# configdiff\n\n**Semantic diff for config files — JSON, YAML, TOML. See what actually changed, not just line noise.**\n\nStop staring at `diff` output trying to figure out if your YAML actually changed. `configdiff` parses both files into structured data and tells you exactly what was added, removed, changed, or type-changed — with full path information.\n\n## Why?\n\nConfig files get messy. A regular `git diff` shows you line changes, but what you actually care about is:\n\n- \"Did the database port change?\"\n- \"What new keys were added?\"\n- \"Did this value change type from string to number?\"\n\n`configdiff` answers those questions directly. It understands the structure of your configs, not just the text.\n\n## Install\n\n```bash\nnpm install -g configdiff\n# or\nnpx configdiff old.json new.json\n```\n\n## Quick Start\n\n```bash\n# Compare two JSON files\nconfigdiff config-old.json config-new.json\n\n# Compare YAML (e.g., k8s manifests before/after Helm upgrade)\nconfigdiff values.yaml values-new.yaml\n\n# Compare TOML (e.g., pyproject.toml after dependency update)\nconfigdiff pyproject.toml pyproject.toml.bak\n\n# Cross-format (JSON vs YAML — same structure)\nconfigdiff config.json config.yaml\n\n# JSON output for scripts and CI\nconfigdiff a.json b.json --json\n```\n\n## Real-World Examples\n\n### 1. Helm Values Review\n\nYou just ran `helm upgrade` and want to verify exactly what changed in the rendered manifests:\n\n```bash\n# Render before and after\nhelm template myapp ./mychart -f values.yaml \u003e before.yaml\nhelm template myapp ./mychart -f values.new.yaml \u003e after.yaml\n\n# See the semantic diff\nconfigdiff before.yaml after.yaml\n```\n\nOutput:\n```\n~ image.tag: \"1.2.3\" → \"1.3.0\"\n+ replicaCount = 3\n~ resources.memory: \"256Mi\" → \"512Mi\"\n\n3 differences: 1 added, 0 removed, 2 changed, 0 type-changed\n```\n\n### 2. CI Gate for Config Changes\n\nBlock PRs that unintentionally change production config values:\n\n```bash\n#!/bin/bash\n# .github/workflows/config-guard.yml\nconfigdiff config/production.json config/staging.json --json | \\\n  node -e \"\n    const changes = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));\n    const risky = changes.filter(c =\u003e c.path.includes('database') || c.path.includes('secrets'));\n    if (risky.length) { console.error('Risky config changes detected!'); process.exit(1); }\n  \"\n```\n\n### 3. Dependency Config Audit\n\nTrack what changed in your `pyproject.toml` after updating dependencies:\n\n```bash\nconfigdiff pyproject.toml.bak pyproject.toml\n```\n\nOutput:\n```\n+ dependencies[2] = \"pydantic\u003e=2.0\"\n~ dependencies[0]: \"fastapi\u003e=0.95\" → \"fastapi\u003e=0.100\"\n~ tool.pytest.testpaths[0]: \"tests\" → \"test\"\n\n3 differences: 1 added, 0 removed, 2 changed, 0 type-changed\n```\n\n## Output Format\n\n```\n~ database.host: \"localhost\" → \"prod-db.example.com\"\n+ database.ssl = true\n+ features[2] = \"monitoring\"\n~ version: \"1.0.0\" → \"2.0.0\"\n+ timeout = 30\n\n5 differences: 3 added, 0 removed, 2 changed, 0 type-changed\n```\n\nSymbols:\n- `+` added\n- `-` removed\n- `~` changed\n- `!` type-changed (e.g. string → number)\n\n## How It Compares\n\n| Feature | `configdiff` | `jq diff` | `d2` | `git diff` |\n|---------|-------------|-----------|------|------------|\n| Semantic (structure-aware) | ✅ | ❌ (manual) | ❌ | ❌ |\n| YAML support | ✅ | ❌ | ❌ | text only |\n| TOML support | ✅ | ❌ | ❌ | text only |\n| Cross-format compare | ✅ | ❌ | ❌ | ❌ |\n| Zero dependencies | ✅ | ❌ | ❌ | ✅ |\n| CI exit codes | ✅ | manual | ❌ | ✅ |\n| Type change detection | ✅ | ❌ | ❌ | ❌ |\n\n## API\n\n```js\nconst { compare, formatHuman, diff, parse } = require('configdiff');\n\n// Compare two config texts\nconst changes = compare(jsonA, jsonB, 'json', 'json');\nconsole.log(formatHuman(changes));\n\n// Or diff already-parsed objects\nconst changes2 = diff({ a: 1 }, { a: 2 });\n\n// Parse config text\nconst obj = parse(yamlText, 'yaml');\n```\n\n### `compare(textA, textB, formatA, formatB?)`\n\nReturns an array of change objects:\n```js\n{ path: ['database', 'host'], type: 'changed', oldValue: 'localhost', newValue: 'prod' }\n```\n\n### `diff(objA, objB)`\n\nCompare two already-parsed objects directly.\n\n### `parse(text, format)`\n\nParse config text into an object. Format: `'json'`, `'yaml'`, or `'toml'`.\n\n## What It Handles\n\n- **JSON** — full support\n- **YAML** — nested keys, arrays (block + inline/flow), inline maps, comments, quoted/unquoted strings\n- **TOML** — tables, arrays of tables, dotted keys, inline values\n- **Cross-format** — compare JSON against YAML, TOML against JSON, etc.\n\n## Zero Dependencies\n\nJust Node.js \u003e= 16. Nothing else.\n\n## Exit Codes\n\n- `0` — no differences\n- `1` — differences found (useful in CI)\n- `2` — error (invalid file, parse error, etc.)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsulthonzh%2Fconfigdiff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsulthonzh%2Fconfigdiff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsulthonzh%2Fconfigdiff/lists"}