Inspiration

Every developer knows the feeling: you clone an unfamiliar repository, open the file tree, and freeze. Hundreds of files, zero mental map. You start grep-ing, jumping between imports, trying to reconstruct in your head a structure that someone else spent months building.

We wanted to eliminate that dead time. The spark was simple what if a codebase could show itself to you, and then talk back when you asked where something was? Combine that with the idea that access to sensitive areas of a system should carry a tangible, physical signal of trust, and BenderBlender was born.


What it does

BenderBlender takes any local repository and turns it into a living, navigable dependency graph in seconds.

  1. Map : point it at any folder on your disk. BenderBlender walks the repo (JS · TS · Python · Dart · Go · Rust · Java · and more) and builds a complete dependency graph between files, resolving relative imports, aliases (@/*), and language-specific conventions like Dart's part of.

  2. Visualize : the graph renders in an Obsidian-style force-directed canvas: circular nodes sized by how many files import them, thin edges tracing dependencies, organic physics that lets the architecture breathe.

  3. Navigate by voice: press the microphone and say something like "take me to the authentication layer". For the graph search and navigation, BenderBlender uses Qwen 3 32B via Groq: an open-source model that delivers near real-time inference, shortlisting the most relevant entry points and refining the result through neighboring connections to move the visual focus to the right node. For the actual file content interpretation, however, everything runs locally via Ollama with Gemma4: since reading your source code means handling potentially sensitive logic, we deliberately keep that step off the cloud. The summary is then read aloud through ElevenLabs TTS.

  4. Security-aware : a hardware privilege badge in the corner detects in real time whether a Ledger USB device is connected. It's a small but deliberate signal: developer tooling should be conscious of the security context it runs in.


How we built it

The stack is intentionally lean one Next.js app, no database, no backend infra to manage.

Analysis pipeline

walker → language extractors → import resolver → graph builder → metrics

  • globby walks the file tree respecting .gitignore.
  • Per-language regex extractors pull raw import strings from JS/TS, Python, Dart, and a generic fallback for everything else.
  • The resolver maps those strings to actual file nodes: it handles relative paths, @/* TypeScript aliases, Dart package: URIs, and part/part of declarations.
  • The graph layer assigns degree-based sizes and marks entry points (files nobody else imports).

Visualization

react-force-graph-2d drives the canvas with D3 force simulation. Node sizes encode import weight; the layout self-organises so hubs naturally float to the centre.

AI navigation

The /api/navigate route sends a shortlist of high-degree nodes to Qwen 3 32B through the Groq API. The model picks the best match, the route then checks its direct neighbours for a better fit, and returns both the focus node and a prose summary of the file. If Groq is unreachable the /api/warm probe has already confirmed Ollama is running locally, and the same flow continues with gemma4:e2b the user never sees the switch.

Voice I/O

The browser's SpeechRecognition API captures the query; ElevenLabs eleven_flash_v2_5 converts the AI's summary back to audio.

Hardware security layer

A polling endpoint probes ioreg (macOS) or lsusb (Linux) every 2.5 seconds for Ledger USB identifiers (vendor id 2c97 or the string ledger). The result drives the Granted Privileges badge a live, hardware-anchored signal of the operator's security posture.

AI subnodes

The .algo/ folder stores pre-computed AI expansions for nodes. Clicking the small handle on any node overlays these synthetic subnodes on the graph, letting teams annotate the architecture with AI-generated semantic structure without modifying source files.


Challenges we ran into

Import resolution across languages is genuinely hard. A TypeScript @/lib/utils alias, a Dart package:my_app/src/auth.dart URI, and a Python relative ..models.user all mean "this file depends on that one" but each requires a completely different resolution strategy. We ended up with a layered resolver that tries each strategy in order and degrades gracefully to a path-similarity heuristic when nothing else matches.

Graph performance at scale surprised us. Force-directed layouts are $O(n^2)$ per tick by default. Repos with thousands of files brought the canvas to a crawl. We had to tune the D3 force parameters aggressively lowering alpha decay, capping velocities, and pruning the weakest edges from the visual layer while keeping them in the underlying data to stay interactive up to the 5 000-node cap.

LLM latency vs. voice UX is a tension that doesn't resolve cleanly. A voice interaction demands sub-second feedback; a model round-trip takes 1–3 s. We worked around it by streaming a "navigating…" animation immediately and queuing the TTS playback to start the moment the first sentence of the summary arrives, so the perceived wait is much shorter than the actual one.


Accomplishments that we're proud of

  • A zero-setup onboarding flow: paste a path, press Map, and in under ten seconds you have an interactive model of a codebase you've never seen before.
  • Graceful AI fallback that degrades from cloud to local without any user-visible disruption the navigator keeps working offline.
  • A polyglot resolver that correctly handles at least five distinct import conventions without requiring any project-level configuration from the user.
  • The .algo subnode system a non-destructive way to overlay AI-generated semantic structure on top of a real dependency graph, opening the door to team-shared annotations.

What we learned

The hardest part of developer tooling is not the AI it's the parsing. Language ecosystems accumulate years of edge cases, and any tool that tries to understand code statically will hit them all. We learned to embrace "good enough" resolution and make the uncertainty visible in the UI rather than hiding it.

We also learned that voice as a navigation primitive is far more natural for spatial interfaces than we expected. Once the graph is rendered and you're oriented inside it, saying "go to the router" feels more direct than clicking through a file tree. The modality fits the task.


What's next for Bender Blender

  • Multi-repo views overlay two repositories on the same canvas to visualise shared dependencies or microservice boundaries.
  • Diff mode compare the graph before and after a pull request to surface architectural impact at a glance.
  • Team .algo annotations sync AI subnodes via a shared backend so the whole team benefits from one person's exploration.
  • IDE plugin bring the same voice-navigable graph directly into the editor, so the context switch disappears entirely.
  • Expanded hardware signals extend the privilege model beyond Ledger to other physical security keys (YubiKey, etc.) and let it gate access to sensitive node expansions.

Built With

  • elevenlabs
  • gemma4
  • globby
  • next.js
  • ollama
  • qwen3
  • react-forge-graph-2d
  • tailwind
  • typescript
  • webspeechapi
Share this project:

Updates