regl: Fast Functional WebGL Framework
regl is a fast, functional WebGL framework that simplifies graphics programming by abstracting the WebGL API into "resources" and "commands." It emphasizes a data-flow approach, minimizing shared state to optimize performance. Instead of direct WebGL calls, developers define declarative commands describing the entire state for a draw call, which regl then compiles into optimized JavaScript. The current stable version is 2.1.1, last published a year ago as of November 2024. regl does not adhere to a strict release cadence, with updates occurring as needed for fixes and features. Its key differentiators include its functional paradigm, automatic state batching for performance, and a minimalistic API compared to raw WebGL, which appeals to users looking for a less verbose and more declarative approach to real-time graphics while maintaining high performance and stability.
Common errors
-
GLSL shader compilation failed: ERROR: 0:1: 'precision' : syntax error
cause Invalid GLSL syntax or incompatible shader version for the WebGL context.fixReview the `frag` and `vert` shader strings for syntax errors, missing semicolons, incorrect variable declarations, or unsupported features. Check WebGL context version compatibility for specific GLSL features. -
WebGL context lost. Unable to recover from software mode. Please restart your browser and reload the Viewer.
cause The browser's WebGL context has been lost, often due to system resource exhaustion, GPU driver issues, or the browser moving the tab to a different GPU process.fixReload the browser tab or restart the browser. For programmatic handling, implement the context loss and restoration listeners described in the warnings. -
TypeError: regl is not a function
cause The `regl` module's default export is a factory function that needs to be called to instantiate the `REGL` object. This error occurs if `require('regl')` or `import createREGL from 'regl'` is used without immediately invoking it.fixEnsure you call the imported `regl` factory function, typically as `const regl = require('regl')();` or `import createREGL from 'regl'; const regl = createREGL();`.
Warnings
- gotcha When developing with `regl`, especially when using tools like Browserify, runtime error messages and sanity checks are removed by default in production builds to reduce bundle size. This can make debugging difficult in deployed applications.
- gotcha WebGL contexts can be lost by the browser due to various reasons (e.g., system resource constraints, GPU driver updates, switching GPUs). While `regl` includes basic context loss handling since v1.0.0, applications must be prepared to re-initialize all GPU-resident resources (textures, buffers, shaders) on a `webglcontextrestored` event.
- gotcha WebGL resources (buffers, textures, framebuffers, etc.) consume GPU memory. Failing to explicitly `destroy()` these resources when they are no longer needed can lead to memory leaks, especially in applications that frequently create and destroy dynamic content.
- breaking In `regl` versions prior to `0.6.0`, the order of arguments for dynamic functions was `(props, context)`. This was changed to `(context, props)` in `v0.6.0` to align with a more consistent pattern.
Install
-
npm install regl -
yarn add regl -
pnpm add regl
Imports
- regl
import { regl } from 'regl'; // Incorrect named import, it's a default export (factory) const regl = require('regl'); // Missing function call to initializeimport createREGL from 'regl'; const regl = createREGL();
- regl (CommonJS)
const regl = require('regl')(); - REGL (TypeScript Type)
import { REGL } from 'regl'; // Imports the runtime value, not just the typeimport type { REGL, Buffer, Texture } from 'regl';
Quickstart
const regl = require('regl')();
const drawTriangle = regl({
frag: `
precision mediump float;
uniform vec4 color;
void main() {
gl_FragColor = color;
}`,
vert: `
precision mediump float;
attribute vec2 position;
void main() {
gl_Position = vec4(position, 0, 1);
}`,
attributes: {
position: regl.buffer([
[-2, -2],
[4, -2],
[4, 4]
])
},
uniforms: {
color: regl.prop('color')
},
count: 3
});
regl.frame(({time}) => {
regl.clear({
color: [0, 0, 0, 0],
depth: 1
});
drawTriangle({
color: [
Math.cos(time * 0.001),
Math.sin(time * 0.0008),
Math.cos(time * 0.003),
1
]
});
});