gl-matrix
A JavaScript vector and matrix math library hand-tuned for high-performance WebGL and real-time 3D graphics applications.
Repository Health
Technical Analysis
gl-matrix is the de facto standard vector and matrix math library for JavaScript WebGL applications, created by Brandon Jones with major contributions from Colin MacKenzie IV. It provides column-major mat2/mat2d/mat3/mat4 matrices, vec2/vec3/vec4 vectors, and quat/quat2 (dual quaternion) types, each with dozens of hand-written operations - multiply, invert, transpose, slerp, decompose - tuned individually for JavaScript engine performance rather than derived from a shared generic implementation.
The library has shipped since 2011 and remains the math backbone behind countless WebGL engines, physics simulations, and browser-based 3D tools, with over 9 million weekly npm downloads. Recent versions ship as tree-shakeable ES modules with generated TypeScript declarations, while retaining a runtime-configurable array backend (Float32Array vs plain Array) so consumers can trade precision for raw execution speed depending on target browser and hardware.
What You Get
- Full mat2/mat2d/mat3/mat4 matrix types with create, multiply, invert, transpose, and decompose operations
- vec2/vec3/vec4 vector types covering the common WebGL transform, lighting, and interpolation operations
- quat and quat2 (dual quaternion) types for rotation and rigid-body transforms, including slerp
- A runtime-switchable array backend (Float32Array vs plain Array) via glMatrix.setMatrixArrayType()
- Generated TypeScript declarations plus per-module ESM entry points (./mat4, ./vec3, …) for tree-shaking
Common Use Cases
- Building view, projection, and model matrices for a WebGL or WebGPU renderer
- Implementing physics and animation interpolation with quaternion slerp
- Powering the math layer of browser-based 3D visualization, modeling, and CAD tools
- Teaching linear algebra and transform concepts in WebGL tutorials and textbooks
Under The Hood
Architecture
gl-matrix has a flat, purely functional module architecture: src/index.js re-exports ten independent modules (common.js, mat2.js, mat2d.js, mat3.js, mat4.js, quat.js, quat2.js, vec2.js, vec3.js, vec4.js), each exporting a stateless namespace of functions that take a pre-allocated out parameter to avoid allocation, following an explicit out/a/b argument convention documented across every function. There is no class hierarchy and no dependency injection, only a single piece of shared mutable state - common.js’s ARRAY_TYPE global, toggled via setMatrixArrayType - that every module reads when constructing new typed arrays. Because the entire public API is built around a shared flat numeric-array shape (mat4 as a 16-element array, quat as a 4-element array) rather than an opaque type, changing that convention or the ARRAY_TYPE default would ripple through all ten modules and every consumer call site.
Tech Stack The shipped library has zero runtime dependencies - plain ES2015+ JavaScript operating on native typed arrays. Build tooling is Babel for the ESM output under dist/esm, Rollup (with terser and size-snapshot plugins) for the legacy UMD bundle, and TypeScript’s tsc invoked in declaration-only mode purely to generate dist/index.d.ts from the plain JS plus a hand-authored types.d.ts - the library itself is not written in TypeScript. Documentation is generated via jsdoc from inline comments, and package.json declares per-module ESM exports (./mat4, ./vec3, etc.) for tree-shaking.
Code Quality Tests live under spec/gl-matrix/, one spec file per module plus a common and worker spec, totaling several thousand lines written in Jasmine-style BDD syntax (describe/it/beforeEach) but executed through mocha with @babel/register. Coverage is extensive and per-function, including edge cases like non-invertible matrices. Error handling is minimal to nonexistent by design - functions assume well-formed numeric-array input and do not validate or throw, a deliberate trade-off for the library’s stated ‘stupidly fast’ performance goal. There is no linter or formatter configuration in the repo, and the only visible CI is a legacy Travis config. Naming is highly consistent across all ten modules, following the same create/clone/copy/multiply/invert argument order everywhere.
API Design gl-matrix’s defining technical choice is trading an idiomatic object-oriented vector/matrix API for a C-like out-parameter convention - every function takes a pre-allocated output array as its first argument - purely to avoid per-call heap allocation and GC pressure inside hot render loops. This pattern is uncommon among general-purpose math libraries but standard in real-time graphics code, which is why it is cited directly in WebGL textbooks as the reference math implementation. Its secondary distinguishing trait is the runtime-swappable ARRAY_TYPE, letting consumers empirically pick the faster representation per browser JIT rather than being locked into one. Getting started requires learning the out-parameter convention up front, but from there the API surface across all ten modules is uniform and predictable.