OGL, a Minimal WebGL 2 Engine

OGL 4,660 (github.com/oframe/ogl (https://github.com/oframe/ogl 4,660 ), Unlicense, 1.0.11, about 4,700 stars) sits between twgl 3,005 and Three.js 30,815 : a scene graph (Transform), Camera, Mesh, geometry primitives, glTF loading and orbit controls, with a Three.js-like API, while every material is your own GLSL. It ships as plain ES modules with no build step, so a page imports straight from src/. Here is Depth, Culling, Blending's shelf again in 28 lines:

BookNest's shelf as OGL meshes sharing one box geometryHTMLLive
<script type="module">
import { Renderer, Camera, Transform, Box, Program, Mesh, Color }
  from 'https://cdn.jsdelivr.net/npm/ogl@1.0.11/src/index.js';
const renderer = new Renderer({ width: 600, height: 170, dpr: 2, antialias: true });
const gl = renderer.gl;                                  // WebGL 2 unless you ask for 1
document.body.appendChild(gl.canvas); gl.clearColor(0.93, 0.91, 0.87, 1);
const camera = new Camera(gl, { fov: 32, aspect: 600 / 170 });
camera.position.set(0.6, 0.6, 2.8); camera.lookAt([0.15, -0.1, 0]);
const scene = new Transform(), geometry = new Box(gl);  // one geometry, seven meshes
const material = (hex) => new Program(gl, {
  vertex: `attribute vec3 position, normal; uniform mat4 modelViewMatrix, projectionMatrix;
    uniform mat3 normalMatrix; varying float vLight;         // light from above and front
    void main() { vLight = max(dot(normalize(normalMatrix * normal), vec3(0.3, 0.8, 0.6)), 0.);
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }`,
  fragment: `precision highp float; uniform vec3 uColor; varying float vLight;
    void main() { gl_FragColor = vec4(uColor * (0.7 + 0.5 * vLight), 1.0); }`,
  uniforms: { uColor: { value: new Color(hex) } },
});
['#1f5f8b', '#5b3f99', '#e09a10', '#3f7d3a', '#b5452f', '#2a9d8f'].forEach((hex, i) => {
  const book = new Mesh(gl, { geometry, program: material(hex) });
  book.scale.set(0.42, 0.98, 0.12); book.position.x = 1.6 * (-0.81 + 0.32 * i);
  book.rotation.y = (30 - 12 * i) * Math.PI / 180; book.setParent(scene);
});
const plank = new Mesh(gl, { geometry, program: material('#8a6240') });  // under the books
plank.scale.set(3.5, 0.06, 0.8); plank.position.y = -0.52; plank.setParent(scene);
renderer.render({ scene, camera });
window.__done = true;
</script>
Browser output of Listing 3.159
Browser output of 159

OGL's modelViewMatrix and normalMatrix are MVP Matrices's matrices: the pipeline stays visible. It suits shader-driven creative sites where Three.js would be unused weight; its repository was last updated in April 2025.