Build with handles
Start with familiar scenes, meshes, materials, lights, cameras, glTF imports, and post effects. Constructors are explicit and every async boundary is visible.
Make your first scene →Yawn gives you approachable TypeScript handles on day one, direct shared-memory performance when you need it, and a programmable render core when your ideas outgrow conventions.
import { Scene, Mesh, PBRMaterial }
from "@yawn/handles";
const scene = new Scene(canvas);
await scene.ready;
const blue = new PBRMaterial(scene, {
baseColor: [0.12, 0.58, 1, 1],
roughness: 0.35,
});
const triangle = new Mesh(scene, {
material: blue,
vertexData: { positions, indices },
});
You do not have to choose between an easy API and a serious foundation. Yawn keeps those layers separate, so learning more never means starting over.
Start with familiar scenes, meshes, materials, lights, cameras, glTF imports, and post effects. Constructors are explicit and every async boundary is visible.
Make your first scene →Positions, cameras, lights, materials, and your own application rows live in one SharedArrayBuffer. Hot updates become direct typed-array writes.
Understand the fast path →Use core directly when you need custom resources, WGSL pipelines, compute, pass dependencies, transient aliasing, and up-front GPU loadouts.
Go beneath handles →Yawn pays setup costs when your scene or graph changes. During play, ordinary updates stay in shared rows that JavaScript and the render worker can both see.
Give Yawn a canvas and await one clear readiness promise.
new Scene(canvas)
Materials and meshes own typed handles, not hidden global state.
new Mesh(scene, options)
After setup, ordinary property updates write into shared rows.
mesh.position.x += 0.1
The playground includes TypeScript intelligence, reusable snippets, live output, shareable SQLite-backed revisions, and the engine’s real GPU profiler.