Interactive 3D visualization of your node_modules dependencies with RLLM-powered queries. Watch in real-time as the AI traverses your dependency graph to answer questions about duplicates, sizes, and relationships.
- π¦ Parse any node_modules - Analyzes package.json files, calculates sizes, detects duplicates
- π― Real-time Visualization - 3D force-directed graph with live highlighting as RLLM explores
- π€ AI-Powered Queries - Ask natural language questions about your dependencies
- π Proxy Hooks - Tracks every property access via JavaScript Proxies for visualization
cd examples/node-modules-viz
pnpm install
pnpm startThen open http://localhost:3000 in your browser.
This runs both the backend (WebSocket + RLLM) and frontend (Vite + React) concurrently.
This will:
- Parse the parent directory's
node_modules(this repo) - Show the 3D visualization
- Let you click example queries or type your own
pnpm server --target=/path/to/your/projectpnpm server --query="Find the largest packages"Or just use the interactive UI in the browser!
pnpm server --target=~/projects/my-app --query="What brings in lodash?"Which packages have multiple versions installed?
What brings in lodash? Show the dependency chain.
How much disk space could I save by deduping?
Find the 5 largest packages and their total size.
What's the path from react to scheduler?
Which packages have the most dependents?
Find all MIT licensed packages.
Find circular dependencies in the graph.
How many packages are dev dependencies vs production?
Show all packages where different versions are required by different dependents.
The parser walks your node_modules directory recursively:
- Reads each
package.json - Calculates disk size
- Detects hoisting and nesting
- Identifies duplicate versions
The graph context is wrapped in recursive JavaScript Proxies:
const trackedContext = createTrackedGraph(context, (event) => {
// When RLLM code accesses context.packages["lodash@4.17.21"]
// This callback fires and sends the event to the browser
server.sendAccessEvent(event);
});The AI writes JavaScript code that runs in a V8 isolate:
// Example: Find duplicates
const duplicates = [];
for (const [name, ids] of Object.entries(context.packagesByName)) {
if (ids.length > 1) {
const sizes = ids.map(id => context.packages[id].diskSize);
duplicates.push({ name, versions: ids, totalSize: sizes.reduce((a,b) => a+b) });
}
}
giveFinalAnswer({ message: JSON.stringify(duplicates, null, 2) });Every property access (like context.packages[id]) triggers the Proxy, which emits an event to highlight that node in the visualization.
The browser receives WebSocket events and highlights nodes as they're accessed:
- Blue nodes = regular packages
- Red nodes = duplicate versions
- Green pulse = currently accessed by RLLM
βββββββββββββββββββ
β node_modules/ β
ββββββββββ¬βββββββββ
β parse
βΌ
βββββββββββββββββββ
β Dependency Graphβ
ββββββββββ¬βββββββββ
β wrap in Proxy
βΌ
βββββββββββββββββββ ββββββββββββββββ
β Tracked Context βββββββΆβ RLLM Engine β
ββββββββββ¬βββββββββ ββββββββ¬ββββββββ
β β
β access events β query result
βΌ βΌ
βββββββββββββββββββββββββββββββββββββββ
β WebSocket Server β
ββββββββββββββ¬βββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β Browser (force-graph-3d) β
β - 3D visualization β
β - Real-time highlighting β
β - Stats panel β
βββββββββββββββββββββββββββββββββββββββ
{
id: "lodash@4.17.21",
name: "lodash",
version: "4.17.21",
diskSize: 1234567,
isDuplicate: false,
isHoisted: true,
dependents: ["package-a@1.0.0", "package-b@2.0.0"]
}{
source: "react@18.2.0",
target: "scheduler@0.23.0",
type: "prod",
versionRange: "^0.23.0"
}Create a .env file:
OPENAI_API_KEY=your_key_here
MODEL=gpt-4o-mini # or gpt-4o, gpt-4-turbo, etc.
# Optional: switch provider (openai | anthropic | gemini | openrouter | cerebras)
# PROVIDER=cerebras
# CEREBRAS_API_KEY=your_key_here- Large projects: Parsing may take a minute for huge
node_modules(10k+ packages) - Query complexity: Start simple, let RLLM iterate to solve complex queries
- Visualization: Click and drag nodes, scroll to zoom, the graph auto-rotates
- Results panel: Shows at the bottom when query completes
Make sure the target directory has a node_modules folder:
ls /path/to/project/node_modulesManually navigate to: http://localhost:3000
Check if port 3000 is available:
lsof -i :3000Check your OpenAI API key is set:
echo $OPENAI_API_KEY# Watch mode (auto-restart on changes)
pnpm dev
# Run with verbose logging
pnpm start --query="Your query"Built with:
- RLLM - Recursive Language Models
- react-force-graph-3d - React 3D graph visualization
- Vite + React - Frontend framework
- ws - WebSocket server (port 4242)
Inspired by the Recursive Language Models paper.