{"id":13532438,"url":"https://github.com/homeport/dyff","last_synced_at":"2026-02-28T23:10:28.945Z","repository":{"id":30316889,"uuid":"124592092","full_name":"homeport/dyff","owner":"homeport","description":"/ˈdʏf/ - diff tool for YAML files, and sometimes JSON","archived":false,"fork":false,"pushed_at":"2026-02-22T13:01:35.000Z","size":7953,"stargazers_count":1711,"open_issues_count":69,"forks_count":93,"subscribers_count":10,"default_branch":"main","last_synced_at":"2026-02-22T18:18:20.534Z","etag":null,"topics":["bosh","diff","dyff","go-patch","golang","json","json2yaml","spruce","tool","yaml","yaml-files","yaml2json"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/homeport.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2018-03-09T20:54:05.000Z","updated_at":"2026-02-22T12:42:43.000Z","dependencies_parsed_at":"2023-10-12T06:34:55.860Z","dependency_job_id":"f4d0952f-5770-4840-ab18-9e17c73181e0","html_url":"https://github.com/homeport/dyff","commit_stats":{"total_commits":555,"total_committers":24,"mean_commits":23.125,"dds":0.5459459459459459,"last_synced_commit":"e931f65dc633b24e1098900a3fb29fe4053957e9"},"previous_names":["heavywombat/dyff"],"tags_count":84,"template":false,"template_full_name":null,"purl":"pkg:github/homeport/dyff","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/homeport%2Fdyff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/homeport%2Fdyff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/homeport%2Fdyff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/homeport%2Fdyff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/homeport","download_url":"https://codeload.github.com/homeport/dyff/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/homeport%2Fdyff/sbom","scorecard":{"id":444193,"data":{"date":"2025-08-11","repo":{"name":"github.com/homeport/dyff","commit":"084ab1c120e91b18a9d44dabfeef9ec1d5d4791d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5.8,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":7,"reason":"Found 3/4 approved changesets -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: topLevel 'contents' permission set to 'write': .github/workflows/auto-merge.yml:7","Warn: no topLevel permission defined: .github/workflows/golangci-lint.yml:1","Warn: no topLevel permission defined: .github/workflows/misspell.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/tests.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":1,"reason":"dependency not pinned by hash detected -- score normalized to 1","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/auto-merge.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/homeport/dyff/auto-merge.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/golangci-lint.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/homeport/dyff/golangci-lint.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/golangci-lint.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/homeport/dyff/golangci-lint.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/golangci-lint.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/homeport/dyff/golangci-lint.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/misspell.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/homeport/dyff/misspell.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/misspell.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/homeport/dyff/misspell.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/homeport/dyff/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/homeport/dyff/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/homeport/dyff/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/homeport/dyff/tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/homeport/dyff/tests.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/tests.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/homeport/dyff/tests.yml/main?enable=pin","Warn: goCommand not pinned by hash: .github/workflows/misspell.yml:31","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   4 third-party GitHubAction dependencies pinned","Info:   1 out of   2 goCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:9"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v1.10.2 not signed: https://api.github.com/repos/homeport/dyff/releases/238868130","Warn: release artifact v1.10.1 not signed: https://api.github.com/repos/homeport/dyff/releases/204366572","Warn: release artifact v1.10.0 not signed: https://api.github.com/repos/homeport/dyff/releases/203936227","Warn: release artifact v1.9.4 not signed: https://api.github.com/repos/homeport/dyff/releases/189005359","Warn: release artifact v1.9.3 not signed: https://api.github.com/repos/homeport/dyff/releases/184204655","Warn: release artifact v1.10.2 does not have provenance: https://api.github.com/repos/homeport/dyff/releases/238868130","Warn: release artifact v1.10.1 does not have provenance: https://api.github.com/repos/homeport/dyff/releases/204366572","Warn: release artifact v1.10.0 does not have provenance: https://api.github.com/repos/homeport/dyff/releases/203936227","Warn: release artifact v1.9.4 does not have provenance: https://api.github.com/repos/homeport/dyff/releases/189005359","Warn: release artifact v1.9.3 does not have provenance: https://api.github.com/repos/homeport/dyff/releases/184204655"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"SAST","score":7,"reason":"SAST tool is not run on all commits -- score normalized to 7","details":["Warn: 23 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T06:17:12.081Z","repository_id":30316889,"created_at":"2025-08-19T06:17:12.082Z","updated_at":"2025-08-19T06:17:12.082Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29954583,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T22:53:01.873Z","status":"ssl_error","status_checked_at":"2026-02-28T22:52:50.699Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["bosh","diff","dyff","go-patch","golang","json","json2yaml","spruce","tool","yaml","yaml-files","yaml2json"],"created_at":"2024-08-01T07:01:10.968Z","updated_at":"2026-02-28T23:10:28.888Z","avatar_url":"https://github.com/homeport.png","language":"Go","funding_links":[],"categories":["Data Manipulation","Go","Productivity","json","\u003ca name=\"diff\"\u003e\u003c/a\u003eDiff","golang","JSON / YAML / CSV","Other Text Formats"],"sub_categories":["YAML","Kubernetes","Diff Enhancers"],"readme":"# δyƒƒ /ˈdʏf/\n\n[![License](https://img.shields.io/github/license/homeport/dyff.svg)](https://github.com/homeport/dyff/blob/main/LICENSE)\n[![Go Report Card](https://goreportcard.com/badge/github.com/homeport/dyff)](https://goreportcard.com/report/github.com/homeport/dyff)\n[![Tests](https://github.com/homeport/dyff/workflows/Tests/badge.svg)](https://github.com/homeport/dyff/actions?query=workflow%3A%22Tests%22)\n[![Codecov](https://img.shields.io/codecov/c/github/homeport/dyff/main.svg)](https://codecov.io/gh/homeport/dyff)\n[![Go Reference](https://pkg.go.dev/badge/github.com/homeport/dyff.svg)](https://pkg.go.dev/github.com/homeport/dyff)\n[![Release](https://img.shields.io/github/release/homeport/dyff.svg)](https://github.com/homeport/dyff/releases/latest)\n[![Packaging status](https://repology.org/badge/tiny-repos/dyff.svg)](https://repology.org/project/dyff/versions)\n\n![dyff](.docs/logo.png?raw=true \"dyff logo - the letters d, y, and f in the colors green, yellow and red\")\n\n## Description\n\nA diff tool for YAML files, and sometimes JSON.\n\n`dyff` is inspired by the way the old [BOSH v1](https://bosh.io/) deployment output reported changes from one version to another by only showing the parts of a YAML file that change.\n\nEach difference is referenced by its location in the YAML document by using either the [Spruce](https://github.com/geofffranks/spruce) dot-style syntax (`some.path.in.the.file`) or [go-patch](https://github.com/cppforlife/go-patch) path syntax (`/some/name=path/in/the/id=file`). The output report aims to be as compact as possible to give a clear and simple overview of the change.\n\nSimilar to the standard `diff` tool, it follows the principle of describing the change by going from the `from` input file to the target `to` input file.\n\nInput files can be local files (filesystem path), remote files (URI), or the standard input stream (using `-`).\n\nAll orders of keys in hashes are preserved during processing and output to the terminal, most notably in the sub-commands to convert YAML to JSON and vice versa.\n\n## Command documentation\n\nSee [command documentation](.docs/commands/dyff.md) for details about each command and its flags.\n\n## Use cases and examples\n\n- Show differences between the live configuration of Kubernetes resources and what would be applied (`kubectl` version \u003e= `v1.20.0`):\n\n  ```bash\n  # Setup\n  export KUBECTL_EXTERNAL_DIFF=\"dyff between --omit-header --set-exit-code\"\n\n  # Usage\n  kubectl diff [...]\n  ```\n\n  ![dyff between example with kubectl diff](.docs/dyff-between-kubectl-diff.png?raw=true \"dyff in kubectl diff example\")\n\n  The `--set-exit-code` flag is required so that the `dyff` exit code matches `kubectl` expectations. An exit code `0` refers to no differences, `1` in case differences are detected. Other exit codes are treated as program issues.\n\n  _Note:_ Versions of `kubectl` older than `v1.20.0` did not split the environment variable into field, therefore you cannot use command arguments. In this case, you need to wrap the `dyff` command with its argument into a helper shell script and use this instead.\n\n- Show the differences between two versions of [`cf-deployment`](https://github.com/cloudfoundry/cf-deployment/) YAMLs:\n\n    ```bash\n    dyff between \\\n      https://raw.githubusercontent.com/cloudfoundry/cf-deployment/v1.10.0/cf-deployment.yml \\\n      https://raw.githubusercontent.com/cloudfoundry/cf-deployment/v1.20.0/cf-deployment.yml\n    ```\n\n    ![dyff between example](.docs/dyff-between-deployment-manifest-example.png?raw=true \"dyff between example of two cf-deployment versions\")\n\n- Embed `dyff` into **Git** for better understandable differences\n\n    ```bash\n    # Setup...\n    git config --local diff.dyff.command 'dyff_between() { dyff --color on between --omit-header \"$2\" \"$5\"; }; dyff_between'\n    echo '*.yml diff=dyff' \u003e\u003e .gitattributes\n\n    # And have fun, e.g.:\n    git log --ext-diff -u\n    git show --ext-diff HEAD\n    ```\n\n    ![dyff between example of a Git commit](.docs/dyff-between-git-commits-example.png?raw=true \"dyff in Git example of an example commit\")\n\n- Convert a JSON stream to YAML\n\n    ```bash\n    sometool --json | jq --raw-output '.data' | dyff yaml -\n    ```\n\n- Sometimes you end up with YAML or JSON files, where the order of the keys in maps was sorted alphabetically. With `dyff` you can restructure keys in maps to a more human appealing order:\n\n    ```bash\n    sometool --export --json | dyff yaml --restructure -\n    ```\n\n    Or, rewrite a file _in place_ with the restructured order of keys.\n\n    ```bash\n    dyff yaml --restructure --in-place somefile.yml\n    ```\n\n- Just print a YAML (or JSON) file to the terminal to look at it. By default, `dyff` will use a neat output schema which includes different colors and indent helper lines to improve readability. The colors are roughly based on the default [Atom](https://atom.io) schema and work best on dark terminal backgrounds. The neat output is disabled if the output of `dyff` is redirected into a pipe, or you can disable it explicitly using the `--plain` flag.\n\n    ```bash\n    dyff yaml somefile.yml\n    ```\n\n- Convert a YAML file to JSON and vice versa:\n\n    ```bash\n    dyff json https://raw.githubusercontent.com/cloudfoundry/cf-deployment/v1.19.0/cf-deployment.yml\n    ```\n\n    The `dyff` sub-command (`yaml`, or `json`) defines the output format, the tool automatically detects the input format itself.\n\n    ```bash\n    dyff yaml https://raw.githubusercontent.com/homeport/dyff/main/assets/bosh-yaml/manifest.json\n    ```\n\n## Installation\n\n### FreeBSD\n\nInstall via ports:\n\n```bash\ncd /usr/ports/textproc/dyff\nmake install clean\n```\n\nInstall via package (pkg):\n\n```bash\npkg install dyff\n```\n\n### Homebrew\n\nThe `homeport/tap` has macOS and GNU/Linux pre-built binaries available:\n\n```bash\nbrew install homeport/tap/dyff\n```\n\n### Mise\n\nUsing [mise](https://github.com/jdx/mise) you could do:\n\n```bash\nmise use -g dyff@latest\n```\n\n### MacPorts\n\nOn macOS, `dyff` is also [available via MacPorts](https://ports.macports.org/port/dyff/):\n\n```bash\nsudo port install dyff\n```\n\n### Pre-built binaries in GitHub\n\nPrebuilt binaries can be [downloaded from the GitHub Releases section](https://github.com/homeport/dyff/releases/latest).\n\n### Curl To Shell Convenience Script\n\nThere is a convenience script to download the latest release for Linux or macOS if you want to need it simple (you need `curl` and `jq` installed on your machine):\n\n```bash\ncurl --silent --location https://git.io/JYfAY | bash\n```\n\n### Build from Source\n\nStarting with Go 1.17, you can install `dyff` from source using `go install`:\n\n```bash\ngo install github.com/homeport/dyff/cmd/dyff@latest\n```\n\n_Please note:_ This will install `dyff` based on the latest available code base. Even though the goal is that the latest commit on the `main` branch should always be a stable and usable version, this is not the recommended way to install and use `dyff`. If you find an issue with this version, please make sure to note the commit SHA or date in the GitHub issue to indicate that it is not based on a released version. The version output will show `dyff version (development)` for `go install` based builds.\n\n## Contributing\n\nWe are happy to have other people contributing to the project. If you decide to do that, here's how to:\n\n- get Go (`dyff` requires Go version 1.23 or greater)\n- fork the project\n- create a new branch\n- make your changes\n- open a PR.\n\nGit commit messages should be meaningful and follow the rules nicely written down by [Chris Beams](https://chris.beams.io/posts/git-commit/):\n\u003e The seven rules of a great Git commit message\n\u003e\n\u003e 1. Separate subject from body with a blank line\n\u003e 1. Limit the subject line to 50 characters\n\u003e 1. Capitalize the subject line\n\u003e 1. Do not end the subject line with a period\n\u003e 1. Use the imperative mood in the subject line\n\u003e 1. Wrap the body at 72 characters\n\u003e 1. Use the body to explain what and why vs. how\n\n### Running test cases and binaries generation\n\nRun test cases:\n\n```bash\nginkgo run ./...\n```\n\nCreate binaries:\n\n```bash\ngoreleaser build --clean --snapshot\n```\n\n## License\n\nLicensed under [MIT License](https://github.com/homeport/dyff/blob/main/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhomeport%2Fdyff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhomeport%2Fdyff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhomeport%2Fdyff/lists"}