The Problem: Detection Is Only Half the Battle
Tools like buf, oasdiff, and GraphQL Inspector can tell you when an API contract breaks. But they stop there. The real pain is propagation: finding every consumer, understanding how they use the changed field, writing the fix, and opening PRs. That process takes 2-3 days per breaking change at most orgs.
Ripple, a new open-source tool by Aakash (solo founder, applying to YC), attacks the propagation problem directly. Push a breaking change to your proto, OpenAPI, or GraphQL schema, and Ripple opens fix PRs in every affected consumer repo — in about 15 seconds.
What Ripple Does
Here's a concrete example from the source article. You remove phone_number from user.proto. Ripple:
- Detects that field 3 was removed (breaking)
- Finds affected files:
python-sdk/client.py,node-api/handlers/user.ts,java-gateway/UserService.java - Generates a correct fix for each file (removes the dead field reference)
- Opens 3 PRs with a clear title and explanation
Each PR links back to the original commit. No Slack pings, no waiting.
Under the Hood: Diff Engines
Ripple has custom parsers for 10 contract types:
- OpenAPI / Swagger
- Protobuf / gRPC
- GraphQL
- SQL + Prisma
- AsyncAPI (Kafka, SNS, MQTT)
- Avro (Confluent Schema Registry)
- tRPC (TypeScript)
- Thrift (Apache)
- JSON Schema
- Smithy (AWS)
Each engine understands the semantics of its format. Removing an optional field is fine; removing a required field is breaking. Changing a type is breaking. Adding a required field without a default is breaking.
The Hard Part: Finding Consumers
Finding consumers is genuinely difficult. They live in different repos, reference specs indirectly through generated code, and use wildly varying naming conventions. Ripple uses an ensemble of five strategies:
consumers = set()
consumers |= grep_for_field_name(removed_field) # Basic but fast
consumers |= check_import_graph(spec_file) # Who imports this?
consumers |= query_git_history(spec_file) # Who changed when this changed?
consumers |= check_playbooks(org_config) # Custom rules
consumers |= multi_invoker_detection(spec_file) # Same spec, multiple callers
The git history approach is the most interesting. If user.proto and python-sdk/client.py always change together in commits, they're probably coupled. This is based on research from PropBench, a benchmark of 268 real engineering scenarios with 1,223 consequence files.
Fix Generation and PR Creation
For each consumer file, Ripple generates the fix using:
- Template-based fixes for common patterns (field removal → remove reference)
- LLM-powered fixes for complex cases (Claude generates the correct code)
- Validation — the fix must pass basic syntax checks before opening a PR
Then it opens a PR (GitHub), MR (GitLab), or PR (Bitbucket) with a clear title like: "fix: Remove phone_number reference (field removed in user.proto)". The PR includes an explanation of what changed upstream and the minimal diff.
How It Compares to Dependabot/Renovate
Dependabot bumps library versions. Ripple rewrites your code. Here's the table from the source:
| Dependabot | Ripple | |
|---|---|---|
| What it updates | Library versions | API consumer code |
| Trigger | New version published | Breaking spec change pushed |
| Fix type | Bump version number | Modify actual code |
| Knowledge | Package registry | Your repo's git history |
| Scope | Single repo | Cross-repo propagation |
Dependabot bumps protobuf from 4.0 to 4.1 in your requirements.txt. Ripple rewrites your user_service.py to handle the fact that user.proto no longer has a phone_number field.
The Research: PropBench
Ripple is backed by PropBench, a benchmark of 268 real engineering changes. The analysis found:
- 34% of misses: test files with non-obvious naming
- 26% of misses: same-package files with no naming relationship
- 16% of misses: config/YAML/JSON requiring domain knowledge
- 39% of consequences are cross-package (invisible to single-repo tools)
A simple grep finds 7% of affected files. Adding co-change history from git bumps that to 17-38%. The ensemble approach reaches 82% at the package level.
The takeaway: much of what we call "senior engineering judgment" in change propagation is actually learnable patterns — naming conventions + git history + domain rules.
Installation
Ripple is free and open source. Install it via:
- GitHub: Install the Ripple GitHub App
- GitLab: Visit
your-ripple-server/auth/gitlab→ Authorize - Bitbucket: Visit
your-ripple-server/auth/bitbucket→ Authorize
Webhooks are auto-installed on all your repos. Push a breaking change and watch the fix PRs appear.
Try It
- Landing page:
aakash2408.github.io/ripple - Source:
github.com/Aakash2408/ripple - GitHub App:
github.com/apps/ripple-api
Ripple is looking for 10 teams to try it and give feedback. If you've ever spent a day fixing downstream code after an API change, star the repo or install the app.



