How the 3D Graph Visualization UI Is Implemented in codebase-memory-mcp

The 3D graph visualization UI in codebase-memory-mcp is implemented as a three-layer system: a native C layout engine computes node positions and colors, an embedded HTTP server streams JSON data to a React frontend, and Three.js renders the interactive scene inside a web canvas.

The codebase-memory-mcp project embeds a fully interactive 3D graph viewer directly inside its native binary. Unlike external visualization tools, this implementation ships as a self-contained unit where high-performance C code calculates graph layouts and a modern React-based frontend handles the rendering, all communicated via an internal HTTP server.

Three-Layer Architecture Overview

The visualization pipeline consists of distinct layers that bridge systems-level performance with web-based interactivity:

  1. Native C Layout Engine – Computes spatial coordinates, colors, and sizes using graph theory algorithms.
  2. Embedded HTTP Server – Serves static assets and streams layout data to the browser component.
  3. React + Three.js Frontend – Renders the 3D scene, handles user interactions, and maps data to visual elements.

This architecture allows the tool to process large codebases natively while delivering a smooth, interactive WebGL-based visualization experience.

Native C Layout Engine

The layout calculation happens in src/ui/layout3d.c and its header layout3d.h. This engine prepares graph data before any rendering occurs, ensuring complex repository structures can be processed efficiently without blocking the UI thread.

Ring-Based Layout with Force-Directed Optimization

The algorithm first assigns nodes to a ring-by-directory layout to establish initial positions, then calculates z-coordinates based on call depth to create the 3D effect. Finally, it applies a gentle ForceAtlas2-style local optimization while keeping nodes anchored to their initial ring positions using the LOCAL_ANCHOR_K constant.

/* Place nodes on a ring, assign z-layer, then optimise */
static void compute_layout(graph_t *g) {
    // 1️⃣ ring placement by directory cluster
    place_nodes_on_ring(g);

    // 2️⃣ set z-coordinate from call depth
    assign_z_from_call_depth(g, Z_DEPTH_SPACING);

    // 3️⃣ gentle local optimisation (ForceAtlas2-like)
    for (int i = 0; i < LOCAL_ITERATIONS; ++i) {
        apply_repulsion(g, LOCAL_REPULSION);
        apply_attraction(g, LOCAL_ATTRACTION);
        apply_anchor_springs(g, LOCAL_ANCHOR_K);   // keep nodes near initial ring
    }
}

Color and Size Mapping

Node aesthetics are determined by symbol metadata. The stellar_color() function maps node degree to a color spectrum, while size_for_label() assigns radii based on symbol types (functions, classes, variables, etc.). The engine respects the CBM_UI_MAX_RENDER_NODES environment variable via render_node_limit() to cap rendering complexity for large codebases.

Embedded HTTP Server

Communication between the native engine and the frontend is handled by the embedded server in src/ui/http_server.c and httpd.c. When the UI variant is activated, the binary starts this server to expose two critical endpoints: a static asset directory containing the compiled React application, and a dynamic /graph.json endpoint that serves the processed layout data.

int start_ui_server(void) {
    // … initialise socket …
    http_serve_static_dir("/ui", embedded_assets_dir());
    // The UI loads `/graph.json` which the native side writes:
    write_graph_json(g);
    return http_listen_and_serve();
}

The static assets are compiled into the binary itself via src/ui/embedded_assets.h, ensuring the tool remains a single distributable file without external resource dependencies.

React Frontend with Three.js

The visualization interface lives in the graph-ui/ directory and is built with React, TypeScript, and Three.js (via @react-three/fiber and @react-three/drei). UI components such as buttons and cards reside in graph-ui/src/components/ui/, while the 3D scene logic is centralized in graph-ui/src/GraphScene.tsx.

Scene Composition

The frontend parses the JSON payload from the native server and instantiates Three.js primitives. Spheres represent nodes with positions and colors calculated by the C engine, while lines connect related symbols.

import { Canvas } from '@react-three/fiber';
import { Sphere, Line } from '@react-three/drei';

function GraphScene({ data }: { data: GraphData }) {
  return (
    <Canvas camera={{ position: [0, 0, 500] }}>
      {data.nodes.map(node => (
        <Sphere
          key={node.id}
          args={[node.size]}
          position={node.position}
          onClick={() => selectNode(node.id)}
        >
          <meshStandardMaterial color={node.color} />
        </Sphere>
      ))}
      {data.edges.map(e => (
        <Line
          key={e.id}
          points={[e.source.position, e.target.position]}
          lineWidth={1}
          color="#888"
        />
      ))}
    </Canvas>
  );
}

Interaction handling—including pan, zoom, node selection, and tooltips—is managed through React state, with color consistency maintained by the lib/colors.ts utility library.

Configuration and Entry Points

The UI variant is activated through the CLI entry point at pkg/pypi/src/codebase_memory_mcp/_cli.py when the environment variable CBM_VARIANT=ui is set. Performance tuning is available via CBM_UI_MAX_RENDER_NODES, which triggers the render_node_limit() function in the C layer to prevent browser overload on massive repositories.

Summary

  • Native C Engine (src/ui/layout3d.c): Computes 3D positions using ring-based initialization and ForceAtlas2 optimization, assigns colors via stellar_color(), and limits nodes with render_node_limit().
  • Embedded Server (src/ui/http_server.c): Serves the React bundle from compiled assets and streams graph data as JSON to the frontend.
  • Web Frontend (graph-ui/): Uses React, TypeScript, and Three.js (@react-three/fiber) to render interactive 3D scenes with pan, zoom, and selection capabilities.
  • Self-Contained: All assets are embedded into the binary via embedded_assets.h, requiring no external web server or installation.

Frequently Asked Questions

What technologies power the 3D visualization frontend?

The frontend is built with React and TypeScript, using Three.js for 3D rendering via the React wrappers @react-three/fiber and @react-three/drei. These libraries handle WebGL canvas management, scene composition, and user interactions like camera controls and object selection.

How does the native binary communicate layout data to the browser?

The native binary starts an embedded HTTP server (implemented in src/ui/http_server.c) that exposes a JSON endpoint. The C layout engine writes processed node coordinates, colors, and edges to graph.json, which the React frontend fetches via HTTP request and parses into Three.js objects.

What limits the number of nodes rendered in the 3D graph?

The native engine respects the CBM_UI_MAX_RENDER_NODES environment variable. The render_node_limit() function in src/ui/layout3d.c filters the graph before serialization, ensuring only the most significant nodes are sent to the browser to maintain interactive frame rates.

Can the layout algorithm be customized or replaced?

The layout logic is centralized in src/ui/layout3d.c, specifically within functions like compute_layout(), place_nodes_on_ring(), and the force-simulation loop. Developers can modify the C source to implement alternative algorithms (e.g., hierarchical or circular layouts) by adjusting the initialization and force parameters before rebuilding the binary.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →