Quick start
nanoraster renders GLB files to image bytes from one Rust core, as a native binary on Node.js 22.13 or newer and as WebAssembly in browsers with WebGPU.
nanoraster turns a GLB file into image bytes you own. One request always produces the same pixels, so a render can serve as evidence.
npm install nanorasterSave this as render.mjs and run it with node render.mjs. The camera angles
are written out so you can drag them; phi: 60 and theta: -45 are the
defaults. The live tile renders at 960×720, so its byte count differs, and its
milliseconds drop after the first frame because dragging reuses one renderer;
Reuse the renderer is the same move in your
own code.
import { renderImage } from 'nanoraster';import { readFile, writeFile } from 'node:fs/promises';const glb = Uint8Array.from(await readFile('model.glb'));const image = await renderImage(glb, { format: 'webp', width: 512, height: 512, phi: 60, theta: -45,});await writeFile(image.name, image.bytes);console.log(`wrote ${image.name} (${image.bytes.length} bytes, ${image.mimeType})`);Rendering…
Expected output
wrote render.webp (26628 bytes, image/webp)The result is a plain object: name, bytes, mimeType, and the width and
height the request resolved to. nanoraster never writes to disk, so the bytes
are yours to save, upload or hand to another process. Run the script again and
the bytes are identical: camera, lighting and encoder are fixed for a given
request.
The same call produces PNG, WebP or JPEG (jpg is an alias), or the
unencoded frame with format: 'raw'; see
Format and annotate and
Work with raw pixels. Every rejection is a
RenderError with a stable machine-readable code; see
Handle render failures.
What it does not do
Texture-backed materials, animation, or scene graphs beyond static geometry. The supported profile is factor-only glTF metallic-roughness, and lighting is the studio preset unless you supply a rig. See How it works.