npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@reactgraph/cli

v0.1.2

Published

Pre-computed React project graph for AI-assisted development

Readme

ReactGraph

Pre-computed React project graph for AI-assisted development. Stop Claude Code from searching — start it navigating.

The Problem

When Claude Code works on a React project, more than half its time and tokens go to file discovery — grep/cat cycles burning 30,000–60,000 tokens per task just to understand the codebase.

The Solution

ReactGraph parses your React project with tree-sitter, builds a graph of components, hooks, state stores, context providers, routes, and API calls, then exposes it via an MCP server or a flat file. Claude reads one compact project map and starts coding immediately.

Before ReactGraph: 40+ tool calls to understand the codebase → 60K tokens wasted After ReactGraph: 1 MCP call → ~2–4K token project map → start coding immediately

Quick Start

# Install
bun install -g reactgraph

# In your React project
cd my-react-app
reactgraph init      # detects framework, creates .reactgraph/
reactgraph index     # builds the graph (~2-5 seconds)

After indexing, .reactgraph/ai-context.md is generated automatically — a flat file Claude can read with zero setup.

Connect to Claude Code

Option 1: MCP Server (recommended)

claude mcp add reactgraph -- reactgraph serve

Or add to .mcp.json:

{
  "mcpServers": {
    "reactgraph": {
      "command": "reactgraph",
      "args": ["serve"]
    }
  }
}

Use --watch to automatically update the graph when files change:

{
  "mcpServers": {
    "reactgraph": {
      "command": "reactgraph",
      "args": ["serve", "--watch"]
    }
  }
}

Option 2: Flat File (zero setup)

Add to your CLAUDE.md:

Read .reactgraph/ai-context.md at session start instead of exploring files.

CLAUDE.md Integration

Add these navigation rules to your project's CLAUDE.md:

## Navigation Rules (ReactGraph)

- ALWAYS call reactgraph.get_map() at session start instead of exploring files
- Use reactgraph.get_subgraph(name) before modifying any component or hook
- Use reactgraph.get_file_context(path) for detailed file info before editing
- Use reactgraph.find_nodes({ query: "name" }) to find a node and its connections
- Use reactgraph.impact(target) before refactoring to know what breaks
- Do NOT use grep/find/glob to discover project structure — the graph has it
- If ReactGraph MCP is not available, read .reactgraph/ai-context.md instead

MCP Tools

get_map()

Returns a compact overview of the entire project — routes, components sorted by connectivity, hooks, state stores, context providers, and shared modules.

# REACTGRAPH MAP | 127 components, 43 hooks, 8 stores, 12 routes
# Indexed: 2026-03-22T14:30:00Z | 342 files

## ROUTES
/                  → DashboardPage  [src/app/page.tsx]
/settings          → SettingsPage   [src/app/settings/page.tsx]
POST /api/auth     [src/app/api/auth/route.ts]

## COMPONENTS (top 30 by connectivity)
Dashboard  [src/components/Dashboard.tsx:5]
  renders: MetricsCard, FilterBar
  hooks: useAuth, useDashboardData
  context: ThemeCtx(read)
  state: dashboardStore(read)
  props: none (page component)

## HOOKS
useAuth  [src/hooks/useAuth.ts:3]
  returns: { user, login, logout, isLoading }
  state: authStore(read/write)
  fetches: GET /api/auth/me
  used-by: Dashboard, Sidebar, Header (23 total)

## STATE STORES
authStore  [zustand] [src/stores/auth.ts]
  shape: { user, token, isAuthenticated }
  writers: useAuth
  readers: Dashboard, Sidebar, Header

## CONTEXT PROVIDERS
ThemeCtx  [src/contexts/Theme.tsx] provided-at: App
  consumers: Dashboard, Sidebar, Header (12 total)

get_subgraph(target, depth?)

Zoom into a specific component, hook, or store. Shows all connections up to the given depth.

> get_subgraph("useAuth", depth=2)

useAuth [src/hooks/useAuth.ts:12]
  ├─ reads_store → authStore [src/stores/auth.ts]
  │   └─ reads_store → Dashboard, Sidebar, Header
  ├─ fetches → GET /api/auth/me
  ├─ uses_hook → useState, useEffect
  used-by (23):
  │ ← uses_hook ← Dashboard [src/pages/Dashboard.tsx]
  │ ← uses_hook ← Sidebar [src/components/Sidebar.tsx]
  │ ← uses_hook ← Header [src/components/Header.tsx]

get_file_context(path)

Everything about a specific file — exports, imports, components, hooks, stores, effects, and all relationships.

> get_file_context("src/components/Dashboard.tsx")

FILE: src/components/Dashboard.tsx
EXPORTS: Dashboard (default)
IMPORTS:
  useAuth ← src/hooks/useAuth.ts
  MetricsCard ← src/components/MetricsCard.tsx

COMPONENT: Dashboard (line 5)
  RENDERS: MetricsCard
  HOOKS: useAuth → { user, isLoading }
  STATE: authStore(read)
  CONTEXT: ThemeCtx(read)
  RENDERED BY: App

trace_flow(from, to)

Trace the data flow path between two nodes. Shows how data gets from A to B.

> trace_flow("LoginForm", "/api/auth/login")

LoginForm → POST /api/auth/login

LoginForm [src/components/LoginForm.tsx]
  └─ uses_hook → useAuth [src/hooks/useAuth.ts]
      └─ fetches → endpoint:POST:/api/auth/login

impact(target)

Analyze what would break if a component, hook, or store is changed.

> impact("useAuth")

IMPACT ANALYSIS: useAuth [src/hooks/useAuth.ts]

DIRECT (23 dependents):
  uses_hook ← Dashboard [src/pages/Dashboard.tsx]
  uses_hook ← Sidebar [src/components/Sidebar.tsx]
  uses_hook ← Header [src/components/Header.tsx]

INDIRECT (via components using useAuth):
  App [src/App.tsx]

SAFE TO CHANGE:
  Internal implementation (same return type + same store writes = no breakage)
RISKY:
  Return type shape — 23 consumers destructure { user, login, logout, isLoading }

find_nodes(filters)

Query the graph. Use query to find a node and see all its connections. Use other filters for bulk searches.

> find_nodes({ query: "useUIStore" })

useUIStore [Store] [src/lib/ui-store.ts:69]

reads_store ← Sidebar [src/components/Sidebar.tsx], Header [src/components/Header.tsx]
writes_store ← useUIActions [src/hooks/useUIActions.ts]

> find_nodes({ kind: "Hook", fetches: true })

Found 4 nodes:
  useAuth [Hook] [src/hooks/useAuth.ts:3]
  useDashboardData [Hook] [src/hooks/useDashboardData.ts:5]

> find_nodes({ kind: "Component", orphan: true })

Found 2 nodes:
  DeprecatedBanner [Component] [src/components/DeprecatedBanner.tsx:1]
  OldUserCard [Component] [src/components/OldUserCard.tsx:1]

Available filters: query, name, kind, using_hook, using_store, fetches, orphan

CLI Commands

| Command | Description | |---------|-------------| | reactgraph init | Detect framework, create .reactgraph/ config | | reactgraph index | Build the project graph with progress display | | reactgraph serve | Start the MCP server (stdio transport) | | reactgraph serve --watch | Start MCP server + auto-update on file changes | | reactgraph unused | Find orphan components, unused hooks, dead exports |

How It Works

  1. Walk — finds all .ts, .tsx, .js, .jsx files, respecting .gitignore
  2. Parse — tree-sitter builds ASTs (fast, handles broken code)
  3. Extract — nine extractors run per file in order:
    • imports — import/export graph, path resolution
    • components — function, arrow, memo-wrapped, class components
    • hooks — custom hook definitions + all hook call sites
    • jsx-tree — which components render which, prop passing
    • context — createContext, Provider, useContext tracking
    • state — Zustand, Redux Toolkit, Jotai, Recoil store detection
    • api-calls — fetch, axios, API wrapper call extraction
    • routes — React Router, Next.js App/Pages Router
    • effects — useEffect dependency arrays, cleanup detection
  4. Resolve — two-pass indexing ensures cross-file references (stores, contexts, components) are fully linked regardless of file processing order
  5. Persist — graph saved to .reactgraph/graph.json with SHA256 file hashes for incremental re-indexing
  6. Format — token-optimized structured text output for AI consumption

What It Detects

| Category | What's Tracked | |----------|---------------| | Components | Function, arrow, class, memo/forwardRef wrapped | | Hooks | Custom definitions, all call sites, destructured returns | | Render tree | Which components render which, prop passing | | Context | createContext, Provider wrapping, useContext consumers | | State | Zustand create(), Redux createSlice(), Jotai atom(), Recoil atom() | | Store usage | Readers (useStore, useSelector, useAtomValue) and writers (setState, dispatch, useSetAtom) | | API calls | fetch(), axios.*(), custom API wrappers | | Routes | React Router <Route>, Next.js file-based routing (App + Pages) | | Effects | useEffect/useLayoutEffect deps, cleanup, triggers | | Imports | Full import/export graph with path resolution |

Graph Schema

Node kinds: Component, Hook, BuiltinHook, Context, Route, Module, Store, ApiEndpoint, Type, Util, Constant

Edge kinds: imports, renders, passes_prop, uses_hook, provides, consumes, calls, fetches, reads_store, writes_store, routes_to, type_of

Configuration

After reactgraph init, settings are stored in .reactgraph/config.json:

{
  "srcDirs": ["src"],
  "framework": "next",
  "exclude": ["**/*.test.*", "**/*.spec.*", "**/*.stories.*"]
}

.reactgraph/ is automatically added to .gitignore — it's a local cache, not a shared artifact.

Tech Stack

| Layer | Choice | |-------|--------| | Parser | tree-sitter (TS/TSX/JS/JSX) | | Graph | Custom in-memory with secondary indexes | | CLI | Commander + Ink | | MCP | @modelcontextprotocol/sdk (stdio) | | File watching | chokidar (incremental re-parse) | | Persistence | JSON with file hash caching |

Five runtime dependencies. No databases, no API keys, no Docker.

Development

bun install
bun test           # run tests (37 tests)
bun run build      # compile TypeScript
bun run dev        # run CLI directly

License

MIT