Skip to main content


The luma namespace provides applications with the ability to register GPU Device backends and create Device class instances using the registered backends.

The returned Device instances provides applications with a complete GPU API.

Device Registration

The module defines abstract API interfaces such as Device, Buffer etc and is not usable on its own.

One or more GPU backend modules must be imported from a corresponding GPU API backend module ( and/or and then registered with


To register a device backend, import the corresponding device backend module and then call luma.registerDevices()

import {luma} from '';
import {WebGLDevice} from '';

It is possible to register more than one device to create an application that can work in both WebGL and WebGPU environments.

import {luma} from '';
import {WebGLDevice} from '';
import {WebGPUDevice} from '';
luma.registerDevices([WebGLDevice, WebGPUDevice]);

Register the WebGL backend, then create a WebGL2 context, auto creating a canvas

import {luma} from '';
import {WebGLDevice} from '';

const webglDevice = luma.createDevice({type: 'webgl', canvas: ...});

Create a WebGL 2 context (throws if WebGL2 not supported)

import {luma} from '';
import {WebGLDevice} from '';

const webgpuDevice = luma.createDevice({type: 'webgl', canvas: ...});

Registering Device Backends

Install device modules

yarn add
yarn add
yarn add

To create a WebGPU device:

import {luma} from '';
import {WebGPUDevice} from '';

const device = await luma.createDevice({type: 'webgpu', canvas: ...});

Pre-register devices

import {luma} from '';
import {WebGLDevice} from '';
import {WebGPUDevice} from '';

luma.registerDevices([WebGLDevice, WebGPUDevice]);
const webgpuDevice = luma.createDevice({type: 'best-available', canvas: ...});

Provide devices to createDevice

const webgpuDevice = luma.createDevice({
type: 'best-available',
canvas: ...,
devices: [WebGLDevice, WebGPUDevice]



luma.registerDevices(devices: (typeof Device)[]): void;

Registers one or more devices (device constructors) so that they can be used to create Device instances against that GPU backend. The registered device types will be available to luma.createDevice() and luma.attachDevice() calls.

luma.registerDevices() enables separation of the application code that registers GPU backends from the application code that creates devices.


luma.createDevice({type, ...DeviceProps});

To create a Device instance, the application calls luma.createDevice().

  • type: 'webgl' \| 'webgpu' \| 'best-available'

Unless a device type is specified a Device will be created using the 'best-available' adapter. favors WebGPU over WebGL devices, whenever WebGPU is available.

Note: A device type is available if:

  1. The backend module has been registered
  2. The browser supports that GPU API


luma.attachDevice(handle: WebGL2RenderingContext | GPUDevice, devices: unknown[]);

A Device can be attached to an externally created WebGL2RenderingContext or GPUDevice. This allows applications to use the API to "interleave" rendering with other GPU libraries.

If you need to attach a Device to a WebGL 1 WebGLRenderingContext, see luma.enforceWebGL2().


luma.enforceWebGL2(enforce: boolean = true);

Overrides HTMLCanvasElement.prototype.getContext() to return WebGL2 contexts even when WebGL1 context are requested. Reversible with luma.enforceWebGL2(false);

Since only supports WebGL2 contexts (WebGL2RenderingContext), it is not possible to callluma.attachDevice() on a WebGL1 context (WebGLRenderingContext).

This becomes a problem when using with a WebGL library that always creates WebGL1 contexts (such as Mapbox GL JS v1). Calling luma.enforceWebGL2() before initializing the external library makes that library create a WebGL2 context, that can then attach a Device to.


Since WebGL2 is a essentially a superset of WebGL1, a library written for WebGL 1 will often still work with a WebGL 2 context. However there may be issues if the external library relies on WebGL1 extensions that are not available in WebGL2. To make a WebGL 2 context support WebGL1-only extensions, those extensions would also need to be emulated on top of the WebGL 2 API, and this is not currently done.


  • At least one backend must be imported and registered with luma.registerDevices() for luma.createDevice() or luma.attachDevice() calls to succeed (unless Device implementations are supplied to those calls).