Open-source project
vasturiano/3d-force-graph avatar
vasturiano/3d-force-graph

vasturiano/3d-force-graph: a WebGL component for graphs that need a third axis

3D force-directed graph component using ThreeJS/WebGL

6,423 stars1,019 forksHTMLMIT

At a glance

What is it?
3d-force-graph renders a force-directed graph in three dimensions with ThreeJS and WebGL, using d3-force-3d or ngraph as the physics engine. It is a component, not a framework, and that distinction decides whether it fits your project.
Who is it for?
Adopt 3d-force-graph when you need a live, interactive 3D graph inside a web page and you are comfortable wiring the data and the camera yourself. Do not adopt it if you need server-side rendering, a static export pipeline, or a charting API that handles axes and legends for you; this is a scene, not a chart.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly HTML, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What 3d-force-graph actually is, and who it is for

This is a web component that represents a graph data structure in a three-dimensional space using a force-directed iterative layout. The README describes the rendering layer as ThreeJS/WebGL and the physics layer as either d3-force-3d or ngraph. That split is the whole design. The component owns the scene, the camera, the node and link objects, and the tick loop; you own the node and link arrays.

The intended user is a front-end engineer who already has graph data (nodes with ids, links with source and target) and wants it explorable in a browser rather than drawn as a static diagram. It suits dependency graphs, network topology, and knowledge graphs where the third axis genuinely separates clusters. It does not suit anyone who wants a chart with axes, a legend and a tooltip out of the box. There is no such layer here. The README points to sibling projects for 2D canvas, VR and AR rendering, and to React bindings, which is a signal about how the author expects the component to be consumed: as one piece of an application you are already building.

How the layout and render loop are wired

Two libraries do the work. three-forcegraph builds the node and link objects inside a ThreeJS scene, and three-render-objects owns the renderer, camera and controls. The package declares both as dependencies, alongside three itself, which package.json pins to the range >=0.179 <1. The physics comes from d3-force-3d, a three-dimensional fork of d3-force, or from ngraph.forcelayout3d. The README presents these as alternatives rather than defaults.

The data flow is one-directional in the usual case: you call the graph with your arrays, the layout engine runs its iterations, positions are written onto the node objects, and the renderer draws them each frame. Because the layout is iterative rather than computed once, the graph keeps moving until forces settle, and any change to the data restarts that process. The README's example list reflects this: there are separate examples for dynamic data changes, for fixing nodes after dragging, for manipulating link force distance, and for node collision detection. Those are not decorations. They are the parts of the force simulation you will end up touching.

The repository is organised as src/ plus example/ plus two rollup configs, one for production and one for development. The build script runs rimraf dist followed by rollup -c, and prepare triggers that build, so installing from git produces dist/. The published package exposes dist/3d-force-graph.mjs as the default and module entry, dist/3d-force-graph.min.js as the UMD and unpkg build, and dist/3d-force-graph.d.ts for types.

Installing it and rendering a first graph

The package is on npm under the name 3d-force-graph, and package.json lists it under that name with the jsdelivr and unpkg fields pointing at dist/3d-force-graph.min.js. Install it with your package manager of choice, then import the default export. The package is type: module, so the ESM entry is what a bundler will resolve unless you ask for the umd condition.

bash
npm install 3d-force-graph

The repository's example directory is the reference for usage, and every example is a self-contained index.html under example/. The README links each one, including basic, async-load and large-graph, with a live page and a source link for each. Open the source of example/basic/index.html to see the smallest working setup before adapting it. If the container has no height, you will see nothing, so give the element explicit dimensions in CSS. Loading the graph asynchronously is a separate example in the repository, which is the pattern to copy when the data arrives over the network rather than being inlined.

Where the component stops being the right tool

The honest limitation is that the third dimension is a rendering choice, not an analytical one. A force layout in 3D has the same problem as in 2D: the result is not stable across runs and not readable as a precise quantity. Adding a depth axis makes occlusion worse, not better. Nodes behind other nodes are hidden, and the README's example list includes click-to-focus and fit-to-canvas precisely because keeping the interesting part of the scene in view is manual work.

Scale is the second boundary. The repository ships a large-graph example described as roughly 4k elements. That is the author's own demonstration of the upper end, and the README does not state a ceiling beyond it. Force simulations are iterative, so cost grows with node and link count and with the number of ticks you allow. If your dataset is an order of magnitude larger, the layout engine choice stops being a preference and becomes a constraint, and the README does not document which engine wins at which size.

The third case is static output. If what you need is a PNG or an SVG in a report, a browser-resident WebGL scene is the wrong shape entirely. Nothing in the README describes a server-side or headless rendering path.

Compared with the 2D force-graph from the same author

The closest alternative is force-graph, the 2D canvas version linked from the README. The difference is not cosmetic. The 2D version draws to a canvas, so it does not require WebGL and does not carry a ThreeJS dependency chain. The 3D version renders through ThreeJS and WebGL, which is what makes depth, lighting and camera controls possible, and also what makes it heavier and dependent on the client's GPU.

That trade decides most adoptions. If your graph is dense and the structure is what matters, the 2D canvas version is easier to read and cheaper to run. Choose the 3D component when the spatial arrangement itself carries meaning, or when you need the camera behaviours the README demonstrates, such as orbit controls, fly controls, automatic orbiting, or adding external objects to the scene. Those examples have no 2D counterpart in this repository. The author also publishes VR and AR variants and React bindings, so the same data model travels across all of them.

Maintenance, licence and the cost of upgrading

The repository is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is the standard permissive arrangement, and it carries no copyleft obligation on your own code. The package's own dependency on three is pinned to a range, >=0.179 <1, rather than an exact version, so a fresh install can pull a newer ThreeJS than the one the author built against. That is the main upgrade risk to watch.

The last push to the default branch was on 2026-04-05. The repository is not archived. The release notes were not available, so there is no changelog to read for migration steps between versions; the version in package.json is 1.80.0, and the dependency on three-forcegraph and three-render-objects are both open ranges, which means a transitive update can change rendering behaviour without a version bump in this package. Pin your lockfile if you care about reproducibility. Building from source requires the devDependencies (rollup, Babel, postcss and their plugins) and runs through the build script.

Editorial conclusion

Adopt 3d-force-graph when you need a live, interactive 3D graph inside a web page and you are comfortable wiring the data and the camera yourself. Do not adopt it if you need server-side rendering, a static export pipeline, or a charting API that handles axes and legends for you; this is a scene, not a chart. Verify first that your target browsers expose WebGL and that your node count survives the layout engine you pick, because the README presents d3-force-3d and ngraph as interchangeable physics backends with different performance characteristics and does not state where each one stops being usable.

Frequently asked questions

What is 3d-force-graph used for?

It renders a graph data structure in three-dimensional space using a force-directed iterative layout, with ThreeJS and WebGL drawing the scene. The README positions it for interactive graph exploration in a web page, with examples covering dependency graphs, trees in DAG mode and graphs of roughly 4k elements.

How do I install 3d-force-graph from npm?

Install it with npm install 3d-force-graph and import the default export. The package is type: module and publishes an ESM build at dist/3d-force-graph.mjs plus a UMD build at dist/3d-force-graph.min.js, which is also the unpkg and jsdelivr entry.

Which physics engine does 3d-force-graph use?

The README states it uses either d3-force-3d or ngraph, with three-forcegraph handling the ThreeJS objects. The README does not document which engine is the default or how to switch, so check the source and examples before assuming one.

What is a 3D graph?

In this project it means a graph whose nodes are positioned in three dimensions by a force simulation and drawn with a perspective camera, so clusters can separate along a depth axis. The third axis is a visual arrangement, and the README's examples for click-to-focus and fit-to-canvas exist because keeping the relevant part of that arrangement on screen takes work.

Can you give me some examples of 3D graphs?

The repository ships an example directory with a basic graph, an asynchronous load, a larger graph of roughly 4k elements, directional arrows and moving particles, curved and self links, text and image nodes, custom node geometries, DAG mode trees and a yarn.lock dependency graph. Each example has a live page linked from the README.

Official sources

  1. Issues
  2. License: MIT
  3. Project website
  4. README
  5. vasturiano/3d-force-graph on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/vasturiano-3d-force-graph.svg)](https://hysenlabs.com/projects/vasturiano-3d-force-graph)