Skip to content

spryte ​

A small, fast 2D renderer for the web. Immediate-mode drawing (sprites, bulk particles, shapes, text, clips, blend modes, render targets and custom shaders), batched onto WebGL2, with an automatic Canvas 2D fallback. MIT licensed, no dependencies, about 10 kB of JavaScript.

spryte is the renderer inside every debuff game. It's also a standalone library you can use on any canvas.

ts
import { createRenderer } from "spryte";

const draw = createRenderer(canvas, { smooth: false }); // pixel art
draw.resize(canvas.width, canvas.height);

function frame() {
  draw.begin("#111", 320, 180, canvas.width / 320); // clear colour, logical size, pixels per unit
  draw.sprite(hero, 160, 90, { rotation: 0.2, tint: "#cffb2d" });
  draw.sprites(spark, sparkPositions, liveSparks);     // thousands of particles in one call
  draw.text("hello", 8, 8);
  draw.end();
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);

Why spryte ​

  • Fast where games need it. On our benchmark it's 2–3.8× faster than PixiJS 8 on like-for-like workloads. Its bulk draw.sprites() draws hundreds of thousands of sprites at 60 fps, with no JavaScript per sprite on WebGL2. See the benchmarks.
  • Small. About 10 kB brotli for a small app, against about 88 kB for PixiJS.
  • Immediate mode. There are no display objects to create, pool or destroy. Draw what you want each frame, in order.
  • Verified. Its fast paths, render targets and shaders are checked pixel for pixel against its simple path on a real GPU, and it handles losing the GPU context.
  • Works with debuff, or without it. In debuff, draw in your scenes is spryte. Elsewhere, it's one createRenderer call.

Learn ​

Reference ​