# viser-project/viser: 3D visualisation from Python, rendered in a browser

> A Python library for computer vision and robotics that draws to a web client, so a robot debugging session over SSH works the same as one at your desk.

**viser-project/viser** — Web-based 3D visualization in Python

- Repository: https://github.com/viser-project/viser
- Website: https://viser.studio/main
- Stars: 2,806 · Forks: 226
- Language: Python
- License: Apache-2.0
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/viser-project-viser

## Why the browser client is the whole point

The README lists the feature set, and it is short enough to read in full: an API for visualizing 3D primitives, GUI building blocks such as buttons, checkboxes, text inputs and sliders, scene interaction tools including clicks, selection and transform gizmos, programmatic camera control and rendering, and an entirely web-based client.

That last item is the one everything else hangs off. In robotics and computer vision, your code usually runs on a machine you are not sitting in front of. A browser client means you open a port, ssh a tunnel, and the visualization appears, with no X11 forwarding, no remote desktop and no headless-GL workarounds. The README puts it plainly: easy to use over SSH.

Installation is two lines, and the extras split tells you what is core:

```bash
pip install viser            # Core dependencies only.
pip install viser[examples]  # To include example dependencies.
```

That split is a good sign. The base install pulls websockets, msgspec, numpy, trimesh and imageio, which is the transport plus geometry, and nothing for a specific robot or dataset. Optional extras exist for URDF files through `yourdfpy`, which is the one you will want if your scene is defined by a robot description rather than by primitives.

The README also credits its influences honestly: Pangolin, Dear ImGui, rviz, meshcat and Gradio. Anyone who has used rviz will recognise the aim, and anyone who has used Pangolin will recognise the imperative style.

## The client is React, three.js and Mantine, built ahead of time

The README names the client stack precisely, which is more than most projects do: React, with Vite and Rollup for bundling, three.js through react-three-fiber and drei, Mantine for UI components, and vanilla-extract for stylesheets.

Two of those choices matter for a robotics library. Mantine gives you real form controls rather than custom-drawn widgets, so a parameter slider behaves the way users expect. And react-three-fiber keeps three.js as the renderer while letting the scene be described in React terms, which is why the client can stay small enough to ship as a wheel.

The `pyproject.toml` explains how that gets into the Python package. It builds with hatchling, and the hatch configuration excludes `src/viser/client/.nodeenv` and `src/viser/client/node_modules` from the build, then adds a comment that the client build itself is in `.gitignore` but is still wanted in the distribution. So the compiled client is produced separately and bundled into the wheel, rather than compiled on the user's machine at install time. There is even a `Makefile` target that does exactly that build:

```bash
cd src/viser/client && npm install && npm run build
```

A library that asks you for Node.js only to modify it, and not to install it, is a considerate design. A `sync_client_server.py` script sits in the repository root, which suggests the TypeScript client and the Python server share message definitions that have to be kept in sync.

## MIT in the manifest, Apache-2.0 in the repository metadata

Two licences are stated and they disagree. `pyproject.toml` declares `license = { text="MIT" }`, includes the MIT classifier among its trove classifiers, and the README's citation and client sections carry no licence claim. GitHub records the repository licence as Apache-2.0.

Both are permissive, so the practical difference for most users is small. The real difference shows up in redistribution: Apache-2.0 includes an express patent grant, and MIT does not. For a research library, that grant is worth having, and it is why this kind of mismatch is worth resolving rather than ignoring.

The resolution takes a minute. Open `LICENSE` in the repository root and read it, since that is what a downstream tool, a distro packager or a legal review will look at. If you are only running viser to look at your own robot data, the difference is academic. If you are vendoring it into a product, the file wins over both metadata fields.

The repository otherwise carries the usual research project signals: `pyright` and `typescript-compile` workflow badges, a `pyversions` badge from PyPI, `.pre-commit-config.yaml`, a `.python-version` file, a `.clang-format` file, and a `CLAUDE.md`. Version 1.1.1 shipped on 2026-09-15, and GitHub reports the last push on 2026-09-24 with the repository not archived.

## Version 1.1.0 renamed line_width to thickness

Release notes for a visualization library are unusually worth reading, because naming changes are where users actually get hurt. v1.1.0, from 2026-08-16, renames `line_width` to `thickness` for line and spline objects and changes its meaning to world-space units by default. Anything that rendered a trajectory or a path will need attention, since a line that used to be measured in pixels now scales with distance.

The same release is where viser stopped being a fixed-window viewer. It brings a panel rewrite with resizing and docking, a new `gui.add_panel()` for floating panels, `gui.main_panel` for placement on the default one, `client.local_storage` for reading and writing browser storage, and `GaussianSplatHandle.set_gaussians()` for replacing splat attributes wholesale. Those additions point at interactive applications rather than one-shot debugging.

v1.1.1 on 2026-09-15 shows what maintenance looks like in practice. It adds Trimesh 5 support, uses `inspect.iscoroutinefunction` on Python 3.14, fixes washed-out scene labels with a workaround for a three.js r185 render order regression, and renders label glyphs as supersampled signed distance fields. It also shrinks the client build from 2.8M to 814K, which is the kind of change that decides whether a visualization loads quickly over the SSH connection the library is designed for.

## End-to-end tests run a real browser against the client

The `Makefile` is small and gives away how the project is tested. Unit and end-to-end tests run together under pytest, and there are separate targets for end-to-end runs with capture off, capture on, a headed browser, and a slow-motion debugging mode:

```bash
uv run pytest tests/e2e/ -n auto
```

Running end-to-end tests in parallel with one worker per logical core is a choice with a documented caveat in the Makefile itself: on a machine with very many cores, WebGL contexts contend, and the comment says to pass a smaller `-n <N>` instead. A library that ships instructions for tuning its own test parallelism based on how much GPU contention you have is a library whose tests exercise the renderer.

The capture and headed targets exist because visual regressions are hard to read from a stack trace. `VISER_E2E_CAPTURE=1` retains video and traces on failure, `--video on` records, and `--slowmo 1000` drops to slow motion with a visible browser window.

Installing the end-to-end dependencies takes a Playwright Chromium download, which is the heavy dependency in the dev extra. The repository also has a `benchmarks/` directory, `.test_durations` for test timing data, and an `examples/` tree organised by numbered stages: `00_getting_started`, `01_scene`, `02_gui`, `03_interaction`, `04_demos`. That ordering is the fastest way to learn the library, since interaction comes after the scene and the GUI.

## Design goals live in a technical report, not the README

The README states two goals and then points elsewhere: primitives that are easy for simple visualization tasks but that can be composed into more elaborate interfaces. The elaboration is an arXiv technical report, and the README gives the citation for it, titled Viser: imperative, web-based 3D visualization in Python.

That citation block is worth repeating because it tells you the project's shape. Imperative is the load-bearing word. Instead of declaring a scene as data and reconciling it, you call functions that mutate a live scene, which is why `set_gaussians()` can replace every attribute of a splat and why panels can be added at runtime. For interactive work and debugging loops, imperative code is easier to write and easier to reason about than a declarative scene graph that diffs.

The examples and documentation live at viser.studio, with the technical report on arXiv and a Discord community linked from the README badges. The repository itself adds `docs/`, `tests/`, `benchmarks/`, `src/` and `examples/`.

What the README does not cover is performance on large scenes, multi-user collaboration, or how the library behaves with very large point clouds. The release notes mention performance work in v1.1.0 without specifics, so for those questions the technical report and the issue tracker are where the answers are. The project is Apache-2.0 by repository metadata, MIT by its own manifest, and developed by a group whose names on the citation run from Brent Yi to Angjoo Kanazawa.

## Conclusion

viser sits in a gap that Pangolin and rviz do not fill well: a robotics researcher running code on a GPU box they reach over SSH and wanting a real 3D view with GUI controls, without a display, a X11 forward or a desktop application in the loop. The imperative API is the reason it works, because drawing a mesh is one call and mutating it is another, which is how debugging loops are actually written. Two things to settle first. The licence is stated twice and differently: GitHub records Apache-2.0 while `pyproject.toml` declares MIT, so check the `LICENSE` file before shipping anything built on it. And version 1.1.0 renamed `line_width` to `thickness` and redefined it in world-space units, which is a breaking change that will surface the moment you render lines. Install with `pip install viser`, work through `examples/03_interaction/` to see what the client can send back, and read the technical report on arXiv for the design reasoning the README only gestures at.

## FAQ

### What is viser used for?

It is a 3D visualization library for computer vision and robotics in Python, with an API for primitives, GUI building blocks like sliders and checkboxes, scene interaction tools including clicks and transform gizmos, and programmatic camera control. Because the client is entirely web based, it is designed for inspecting data on a remote machine over SSH.

### How do I install viser?

Use `pip install viser` for the core dependencies, or `pip install viser[examples]` to pull in the extra packages the examples need. There is a separate `urdf` extra based on `yourdfpy` for projects whose scenes come from a robot description file. Node.js is only needed if you are rebuilding the client yourself, which the Makefile's `build-client` target handles.

### Is viser similar to rviz or Pangolin?

It is aimed at the same problems as rviz and Pangolin but renders in a browser rather than an OpenGL window, so it works on a remote machine without X11 forwarding. The README lists Pangolin, Dear ImGui, rviz, meshcat and Gradio as inspirations, and the technical report on arXiv explains the imperative design in more detail.

### What licence is viser released under?

The two published statements differ. `pyproject.toml` declares MIT and includes the MIT trove classifier, while GitHub records the repository as Apache-2.0. Both are permissive, but Apache-2.0 adds an express patent grant, so read the `LICENSE` file at the repository root before vendoring the library into a product.

## Sources

- [License: Apache-2.0](https://github.com/viser-project/viser/blob/main/LICENSE)
- [Project website](https://viser.studio/main)
- [README](https://github.com/viser-project/viser/blob/main/README.md)
- [Releases](https://github.com/viser-project/viser/releases)
- [viser-project/viser on GitHub](https://github.com/viser-project/viser)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/viser-project-viser
