Open-source project
visgl/luma.gl avatar
visgl/luma.gl

luma.gl: a portable WebGPU and WebGL toolkit for data visualization

High-performance Toolkit for WebGL-based Data Visualization

2,483 stars234 forksTypeScriptNOASSERTION

At a glance

What is it?
luma.gl is a modular GPU toolkit from the vis.gl suite that keeps one device API across WebGPU and WebGL 2. It is built for the rendering needs of deck.gl, kepler.gl and streetscape.gl rather than for general 3D apps, and the README points to the website for installation details.
Who is it for?
Adopt luma.gl when your rendering lives inside the vis.gl ecosystem or when you need one code path across WebGPU and WebGL 2 for data-heavy scenes. Do not adopt it as a general 3D engine: the README states its mandate is to support the GPU needs of vis.gl frameworks, and the scene layer is private and experimental.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

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

Editorial analysis

The problem luma.gl solves for visualization engineers

WebGL 2 works everywhere and WebGPU does not. A visualization team that wants WebGPU's compute path today still has to keep a WebGL 2 path for the browsers and devices that lack it, and maintaining two rendering backends doubles the surface area of every shader and every buffer upload. luma.gl's answer is a portable device API that stays close to WebGPU while supporting both WebGPU and WebGL 2, so the same resource and pipeline code can target either backend.

The audience is narrow and stated plainly. The README says that while luma.gl is generic enough for general 3D rendering, its mandate is primarily to support the GPU needs of data visualization frameworks in the vis.gl suite, and it names kepler.gl, deck.gl and streetscape.gl. If you are building a charting layer, a geospatial canvas or a robotics visualization on top of deck.gl, you are the intended user. If you want a scene graph with an editor, you are not.

How the modular architecture is put together

The repository is a monorepo. package.json declares workspaces for dev-modules/*, modules/*, examples/**/* and website, and the private root package is named luma.gl-monorepo. That layout matters more than it sounds: the published artifacts are the packages under modules/, and the README's claim that applications can adopt the modules they need without taking on an independent renderer, a parallel material implementation, or a monolithic scene runtime is a statement about that split.

The layers the README describes run from low-level shaders and resources up to physically based scenes, open 3D assets, animation and data visualization. Concretely, that means portable graphics resources and render pipelines, compute capabilities where WebGPU supports them, composable GLSL and WGSL shader modules, physically based materials with lighting and image-based environments, and shared scenegraph, animation, morph-target, model and resource-management primitives. glTF 2.0 assets, physical materials, skeletal and morph animation and supported glTF extensions are first-class.

The most interesting and least settled piece is @luma.gl/scenes, described as an experimental, private retained scene interface built in the spirit of the ANARI object model. The README is careful here: it is independently developed, inspired by Khronos ANARI concepts, and is not an official ANARI implementation, not certified or conformant, and not affiliated with or endorsed by The Khronos Group. Read that as a boundary, not a disclaimer. The retained scene layer is not a standard you can rely on a third party to implement.

Installing @luma.gl/core and rendering a first frame

The README does not carry install steps. It says only: "For details, please refer to the extensive online website", and the repository's start script opens https://luma.gl/docs/getting-started. The package name is visible in the README badge, which links to https://www.npmjs.com/package/@luma.gl/core, so the entry point for a new project is the @luma.gl/core package. The commands below follow that naming; the exact API surface should be taken from the getting-started page, since the README does not reproduce it.

Install the core package with your package manager of choice:

bash
yarn add @luma.gl/core

The monorepo itself is bootstrapped and built with its own scripts, which is useful if you intend to work against the source rather than the published packages:

bash
yarn bootstrap
yarn build
yarn test

The test script is defined as yarn test-node && yarn test-headless, so a full run needs both a Node environment and a headless browser. That is a real constraint for CI: the headless half is where the GPU code is exercised.

For the rendering side, the README's own framing is the safest guide. It describes a portable device API that stays close to WebGPU, portable graphics resources and render pipelines, and composable GLSL/WGSL shader modules. Start from the getting-started page, pick the modules you need from modules/, and keep the device abstraction as your boundary so the WebGL 2 fallback stays available.

Where luma.gl is the wrong tool

The README sets the boundary itself: the mandate is primarily to support the GPU needs of data visualization frameworks in the vis.gl suite. If your project is a general 3D application with its own asset pipeline, its own scene format and no deck.gl dependency, you are taking on a toolkit whose design decisions were made for someone else's workload.

The private scene interface is the sharpest limitation. @luma.gl/scenes is experimental, private, and explicitly not an official ANARI implementation or a conformant one. Building a product on a private, experimental interface means you cannot count on the ANARI ecosystem for interoperability, and the interface can change without the compatibility guarantees a published standard would carry.

Version state is the second thing to check before you commit. The recent releases list includes v10.0.0-alpha.2 and v10.0.0-alpha.1 alongside v9.4.2. Alphas are alphas. If you need a stable base for a production visualization, the 9.4 line is the one the release list marks as a plain version, and the README's own feature list (WebGPU compute, the scene interface) is the part most likely to move between them.

Finally, the README documents no rollback or migration path between major versions. It points at the website instead. That silence is worth weighing if you are planning an upgrade across the 9 to 10 boundary.

How luma.gl differs from three.js

The obvious comparison is three.js, and the difference is architectural rather than a matter of feature checklists. three.js is a renderer: you get a scene graph, materials, loaders and a renderer object, and you build your application inside its model. luma.gl positions itself as the layer underneath that. Its README says applications can adopt the modules they need without taking on an independent renderer, a parallel material implementation, or a monolithic scene runtime. In practice that means deck.gl can own the scene and the data flow while luma.gl owns devices, resources, pipelines and shader modules.

That also explains the vis.gl orientation. kepler.gl, deck.gl and streetscape.gl are named as the frameworks luma.gl exists to serve, and those are data visualization tools, not game engines. A team rendering millions of data points with attribute updates per frame has different needs from a team rendering a modeled environment. luma.gl's portable device API, compute where WebGPU supports it, and shader module composition are aimed at the first case.

The cost of that positioning is that luma.gl is not a drop-in replacement for a full engine. You bring the scene, the camera, the input handling and the asset workflow, or you get them from deck.gl. What you get in return is one device abstraction across WebGPU and WebGL 2 and a set of primitives that do not assume a particular application model.

Maintenance, licensing and the cost of tracking the monorepo

The repository is not archived, and the last push was on 2026-09-28. Releases in the recent list run from v9.4.2 on 2026-09-19 to v10.0.0-alpha.2 on 2026-09-25, with v10.0.0-alpha.1 on 2026-09-17. That is an actively moving codebase, and the alpha line sitting next to a stable line tells you where the churn is.

Upgrade cost is dominated by the module split. The root package lists workspaces for modules/*, dev-modules/*, examples/**/* and website, and the build script runs a pre-build step inside modules/constants before ocular-build. If you consume published packages, you track them individually; if you build from source, you inherit the monorepo's toolchain, including ocular and its lint, build and publish commands. The test script requires both a Node run and a headless browser run, so any CI you build around the source needs a GPU-capable headless environment.

On licensing: the README carries an MIT badge and links to the LICENSE file at the repository root, and package.json states "license": "MIT". The repository metadata classifies the licence as NOASSERTION, so the two do not agree on paper. The README also notes that the WebGPU logo is W3C material under CC BY 4.0 and that Khronos marks belong to The Khronos Group, and that glTF, WebGL and ANARI trademarks belong to their respective owners. If you redistribute assets or branding, read the LICENSE file and the trademark note rather than the badge.

Editorial conclusion

Adopt luma.gl when your rendering lives inside the vis.gl ecosystem or when you need one code path across WebGPU and WebGL 2 for data-heavy scenes. Do not adopt it as a general 3D engine: the README states its mandate is to support the GPU needs of vis.gl frameworks, and the scene layer is private and experimental. Before committing, check the version of @luma.gl/core you install against the v10.0.0-alpha releases, and confirm which modules you actually need so the monorepo's package count does not become your bundle.

Frequently asked questions

What is luma.gl?

It is a modular GPU toolkit for the web, described in its README as providing portable WebGPU and WebGL rendering, GPU compute and open 3D assets. It is developed in the vis.gl suite and its stated mandate is to support the GPU needs of data visualization frameworks such as kepler.gl, deck.gl and streetscape.gl.

Which npm package do I install to start using luma.gl?

The README's badge links to the @luma.gl/core package on npm, and the repository is a monorepo whose published packages live under modules/. The README itself does not list install steps and points to the online website for them.

Does luma.gl support WebGPU as well as WebGL?

Yes. The README describes a portable device API that stays close to WebGPU while supporting both WebGPU and WebGL 2, with compute capabilities where WebGPU supports them. The same description lists composable GLSL and WGSL shader modules.

Is the luma.gl scene interface an official ANARI implementation?

No. The README states that @luma.gl/scenes is an experimental, private retained scene interface built in the spirit of the ANARI object model, independently developed, and not an official ANARI implementation, not certified or conformant, and not affiliated with or endorsed by The Khronos Group.

What is the licence of luma.gl?

The README shows an MIT badge and links to the LICENSE file, and package.json declares "license": "MIT". The repository metadata itself classifies the licence as NOASSERTION, so the two do not match on paper.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. visgl/luma.gl 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/visgl-luma-gl.svg)](https://hysenlabs.com/projects/visgl-luma-gl)