# Code Impact Radius

> Use BEFORE any rename, refactor, type-shape change, deletion, or "what depends on X" question in a TypeScript / TSX codebase. Returns every place a symbol is defined, read, written, called, instantiated, imported, re-exported, plus its transitive callers up to a configurable depth. Far cheaper than grep+read because it queries a typed reference index built from the TypeScript Compiler — no false positives from string matches in comments or unrelated identifiers with the same name. Triggers on phrases like "what calls X", "where is X used", "blast radius of X", "impact of renaming X", "find all references to X", "who depends on X", "what breaks if I change X".

- Skill: `faris-alanazi/code-impact-radius` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add faris-alanazi/code-impact-radius`
- Raw SKILL.md: https://api.skillmd.com/api/skills/faris-alanazi/code-impact-radius/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Faris-Alanazi (https://skillmd.com/u/faris-alanazi)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/faris-alanazi/code-impact-radius

---


# Code Impact Radius

The structured replacement for `grep -r <name>` followed by reading every match.

## When to invoke

Whenever you (or the user) is about to:

- Rename a function, variable, class, type, interface, or enum
- Change the shape of a type or function signature
- Move or delete a file / module / barrel export
- Audit who depends on a particular symbol (security review, deprecation, refactor planning)
- Decide whether a change is "safe to do alone" or "needs coordinated rollout"
- Answer "what calls X", "where is X used", "who imports X", "blast radius of X"

This is the right tool whenever the question is **"what connects to this symbol?"**

## How to invoke

```bash
node ~/.claude/skills/code-impact-radius/src/cli.js <symbolName> --project <path> --json
```

Or — if you want pretty terminal output instead of JSON:

```bash
node ~/.claude/skills/code-impact-radius/src/cli.js <symbolName> --project <path> --pretty
```

JSON is the default when stdout is not a TTY (so AI agents always get JSON).

### Options

| Flag | What it does |
|---|---|
| `--project <path>` | Project root containing `tsconfig.json` (default: `cwd`) |
| `--depth <n>` | Transitive caller depth (default `2`, max `10`) |
| `--kind <kind>` | Filter declaration kind: `variable` `function` `class` `method` `interface` `type` `enum` |
| `--at <file>:<line>` | Disambiguate when the name has multiple declarations |
| `--include-tests` | Include `*.test.ts` / `*.spec.ts` in references (default: skip) |
| `--max-sites <n>` | Truncate `references.sites` to first N entries |
| `--json` / `--pretty` | Force output mode |
| `--mermaid` | Emit a Mermaid flowchart diagram (paste into a Markdown ` ```mermaid ` block — GitHub, GitLab, VS Code, Obsidian, Notion render natively). |

### Exit codes

| Code | Meaning |
|---|---|
| 0 | Success — exactly one match, OR ambiguous list with N candidates |
| 1 | CLI usage error / runtime error |
| 2 | Symbol name not found |

## Reading the JSON output

```jsonc
{
  "query":             // what was asked
  "matched":           // how many declarations matched the name
  "candidates":        // disambiguation list (only when matched > 1 or 0)
  "symbol": {
    "name":            // canonical name
    "kind":            // function | class | variable | ...
    "definition": {
      "file": "...", "line": 42, "column": 17,
      "snippet": "export function formatPrice..."
    }
  },
  "references": {
    "totalCount": 14,
    "byKind": {
      "definition": 1,
      "call": 8,
      "import": 3,
      "reExport": 1,
      "read": 1,
      "instantiation": 0,
      "jsx": 0,
      "type": 0,
      "write": 0
    },
    "sites": [
      { "file": "...", "line": 18, "kind": "call", "snippet": "formatPrice(price, locale)", "parentKind": "CallExpression" }
    ],
    "truncated": 0
  },
  "imports": {
    "exportedFrom": "src/lib/utils.ts",
    "importedBy":     // every file that imports this symbol
    "reExportedFrom": // every barrel that re-exports it
  },
  "transitiveCallers": {
    "depth": 2,
    "callers": [
      { "depth": 1, "file": "...", "line": 18, "function": "PriceTag",     "functionKind": "FunctionDeclaration" },
      { "depth": 2, "file": "...", "line": 87, "function": "CheckoutPage", "functionKind": "FunctionDeclaration" }
    ]
  },
  "warnings": []
}
```

## Disambiguation flow

If `matched > 1`, the tool returns `candidates` and asks for a `--at <file>:<line>` to pick one:

```bash
$ code-impact-radius id --project ./app --json
# matched: 3, symbol: null, candidates: [{file, line, kind} × 3]

$ code-impact-radius id --project ./app --at src/ambig.ts:11 --json
# matched: 1, symbol: { ... }
```

## Decision-flow guidance for blast-radius checks

Use this output to drive a structured impact table:

1. **Definition** — read the file at `symbol.definition.file:line` to see the contract you're about to change.
2. **References by kind** — every `call`, `instantiation`, `jsx`, `read`, `write` site is a potential breakage.
3. **Imports** — every `imports.importedBy` entry needs updating if you rename the symbol.
4. **Re-exports** — barrels in `imports.reExportedFrom` need updating too.
5. **Transitive callers** — depth 2-3 catches most "indirect callers" that grep would miss.

Then build the impact table (`file:line | usage | status: todo/done/verified-unaffected`) and tick each row off as you go.

## What this tool does NOT cover

- **String literals** — i18n keys (`t('home.title')`), SQL fragments, env-var names, URL paths. Use grep for those.
- **Dynamic imports** — `import('./mod')` calls aren't traced.
- **Cross-language** — TypeScript / TSX only. Python / Rust / Go / SQL stay grep territory.

For string-literal scans, run grep alongside this tool. The two together cover the full surface.

## Performance

Cold-load on a ~200 TS/TSX file project: ~1.5s per query. ~700-file projects: ~5-8s. The TypeScript compiler initializes once per CLI invocation, so repeated queries in one session each pay that cost.

