What RippleCheck does
An AI assistant changes one function and reports success. It was right about that function. What it didn't check is the eleven other files that call it.
That failure mode is specific to fast, confident, wide-reaching edits: the change is locally correct and globally wrong, and you find out later, somewhere else. Reading the diff doesn't help, because the breakage isn't in the diff.
RippleCheck answers one question before you commit: what else touches this?
⚠ getUserSession is used in 3 other places: src/api/auth.ts,
src/pages/login.tsx, src/hooks/useAuth.ts — changing it could affect all of them.
✓ formatBytes isn't used anywhere else — safe to change.RippleCheck never edits your code. It reports impact and can write a fix prompt for you to copy. Applying the fix is always your call. This is a deliberate safety design, not a missing feature.
How it works
RippleCheck resolves real references — not text matches. It uses ts-morph for JavaScript and TypeScript, and Python's own ast module for Python.
For every top-level function, component, and class, it reports the file that defines it and every other file that references it, with line numbers. The scan is static, deterministic, and entirely local. Same input, same output, every time.
1. MCP server
Exposes a check_impact tool to any MCP-compatible client. Best if you want your assistant to check impact on its own, mid-conversation.
$ claude mcp add ripplecheck --scope user -- npx -y ripplecheck-mcpThen ask your assistant to check the impact of a change, or let it call the tool by itself. Any MCP client works — Cursor and other MCP-ready editors use their own config format, but point at the same npx -y ripplecheck-mcp command.
2. Claude Code hooks
For automatic reporting with no prompting at all. The hook runner ships inside the npm package but isn't exposed as a standalone binary, so point at it directly in .claude/settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "node /path/to/ripplecheck/src/hook-runner.js --refresh", "timeout": 10 }
]
}
],
"Stop": [
{
"hooks": [
{ "type": "command", "command": "node /path/to/ripplecheck/src/hook-runner.js --report", "timeout": 20 }
]
}
]
}
}The split is intentional. PostToolUse runs silently after every edit to keep a warm index current. Stop fires once when the assistant finishes its turn and prints a single report covering everything it touched. Reporting after each individual edit would just describe a half-finished state.
3. Desktop app
A standalone app for macOS and Windows that watches a folder and shows impact live. It needs no AI tool, no hooks, and no MCP support — it drives the same scanner directly.
It waits for edits to settle (3.5s by default, configurable) before reporting, so a burst of AI-driven edits across many files arrives as one coherent report instead of one per file. You also get session summaries, a repository-wide risk overview, retesting of individual findings, and optional AI-written summaries if you supply your own API key.
CLI
The npm package publishes two binaries: ripplecheck-mcp (the MCP server above) and ripplecheck (the scanner).
$ npx -p ripplecheck-mcp ripplecheck /path/to/projectPrints the dependency map as JSON, followed by a plain-English summary.
Risk levels
Each finding carries a risk level derived purely from fan-out — how many other files reference the symbol.
| Risk | Meaning |
|---|---|
| ✓ safe | Used nowhere else |
| ⚠ moderate | Used in 1–2 other files |
| ● high | Used in 3 or more other files |
That is the entire heuristic, and it is deliberately simple. It tells you where to look — not how dangerous your particular edit is.
Languages
.js .jsx .ts .tsx, inline <script> blocks in .html, and .py.
Python analysis needs python3 (or py -3 on Windows) on your PATH. If it's missing, Python files are skipped with a note and the JavaScript/TypeScript scan runs normally.
What it can't see
Worth knowing before you rely on it.
- Risk is a fan-out count. Three usages reads as “high” whether the change is a comment tweak or a full signature rewrite.
- Only top-level declarations are tracked. Class methods, object properties, and nested closures are not mapped individually.
- Same-name collisions. Two unrelated functions sharing a name across files can be conflated — especially in the Python path, which links by name rather than by resolved reference.
- Dynamic references are invisible.
obj[methodName](), string-based imports, and runtime dispatch cannot be seen by static analysis. A clean report is not proof that nothing else depends on a symbol. - The first scan of a large repo is slow. A warm index makes later scans fast, but the initial parse scales with project size.
Privacy
RippleCheck has no server. There is nothing to sign in to and nothing to send code to.
- The scan is entirely local. Your code never leaves your machine.
- No accounts, no telemetry, no analytics, no crash reporting.
- Optional AI enrichment is bring-your-own-key. Your key is stored encrypted at rest via Electron's
safeStorage, and requests go only to the provider you chose — never to a RippleCheck server, because there isn't one. - With no key configured, enrichment is skipped silently and the deterministic output is unchanged.
- This website itself sets no cookies and runs no analytics. It does load fonts from Google Fonts.
Build from source
Useful on Intel Macs, on Linux, or if you'd simply rather not run an unsigned binary.
$ git clone https://github.com/RippleCheck/ripplecheck.git
$ cd ripplecheck && npm install
$ npm run app # run it
$ npm run package:mac # -> dist/*.dmg
$ npm run package:win # -> dist/*.exeRequires Node 18 or newer.
Anything deeper
The full README on GitHub is the source of truth and stays current with the code. For bugs and feature requests, use GitHub Issues.