Skip to content
bestmaaPublic

About

Low-level 2D rendering engine for JavaScript and TypeScript—Canvas-first and WebGL2-ready.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

487 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Raw2D

Raw2D is a low-level 2D rendering engine for JavaScript and TypeScript.

It is browser-first, Canvas-first, WebGL2-ready, and built around small isolated modules. Objects store scene data and transform behavior. Renderers draw those objects.

Public docs: https://raw2d.com/doc and markdown reference: https://raw2d.com/readme. Feedback: https://github.com/bestmaa/raw2d/issues. Direct questions: bestemplin@gmail.com.

Why Raw2D Exists

Raw2D is not trying to replace PixiJS or Phaser. Those are powerful high-level engines.

Raw2D is for developers who want:

  • explicit control over the render pipeline
  • small focused classes
  • readable TypeScript internals
  • Canvas as the complete reference renderer
  • WebGL2 batching without hiding too much
  • tooling-friendly APIs for editors, visual tools, and engine experiments

The public pipeline names should stay understandable and testable:

Scene -> RenderList -> Batcher -> Buffer -> Shader -> DrawCall

Performance matters, but the project identity is control, modularity, readable diagnostics, and transparent pipeline steps.

Install

Use the umbrella package first:

npm install raw2d

Focused packages are available for advanced users:

npm install raw2d-core raw2d-canvas raw2d-webgl raw2d-sprite raw2d-text raw2d-interaction raw2d-react raw2d-mcp

Package split rule: app examples should import from raw2d, engine-builder examples may import focused packages, and all Raw2D packages are versioned together so releases stay easy to audit.

CDN usage:

<script src="https://cdn.jsdelivr.net/npm/raw2d@latest/dist/raw2d.umd.cjs"></script>
<script>
  const { BasicMaterial, Camera2D, Canvas, Rect, Scene } = Raw2D;
</script>

Quick Canvas Example

<canvas id="raw2d-canvas"></canvas>
import { BasicMaterial, Camera2D, Canvas, Rect, Scene } from "raw2d";

const canvasElement = document.querySelector<HTMLCanvasElement>("#raw2d-canvas");

if (!canvasElement) {
  throw new Error("Canvas element not found.");
}

const renderer = new Canvas({
  canvas: canvasElement,
  width: 800,
  height: 600,
  backgroundColor: "#10141c"
});

const scene = new Scene();
const camera = new Camera2D();

const rect = new Rect({
  x: 100,
  y: 80,
  width: 180,
  height: 100,
  material: new BasicMaterial({ fillColor: "#35c2ff" })
});

scene.add(rect);
renderer.render(scene, camera);

Canvas Or WebGL

Use Canvas when you want the most complete and easiest renderer path.

import { Canvas } from "raw2d";

const renderer = new Canvas({ canvas: canvasElement });
renderer.render(scene, camera);

Use WebGLRenderer2D when your scene uses supported objects and you want explicit batching, packed-atlas texture reuse, static render runs, opt-in safe sprite sorting, and performance stats.

import { WebGLRenderer2D } from "raw2d";

const renderer = new WebGLRenderer2D({ canvas: canvasElement });
renderer.render(scene, camera);

const stats = renderer.getStats();

console.log(stats.drawCalls);
console.log(stats.textureBinds);
console.log(stats.spriteTextureBindReduction);

Both renderers implement the shared Renderer2DLike contract:

import type { Renderer2DLike } from "raw2d";

function drawFrame(renderer: Renderer2DLike): void {
  renderer.render(scene, camera);
}

Sprite And Texture

import { Camera2D, Canvas, Scene, Sprite, TextureLoader } from "raw2d";

const renderer = new Canvas({ canvas: canvasElement, backgroundColor: "#10141c" });
const scene = new Scene();
const camera = new Camera2D();
const texture = await new TextureLoader().load("/sprite.png");

scene.add(new Sprite({
  texture,
  x: 120,
  y: 80,
  width: 128,
  height: 128,
  origin: "center"
}));

renderer.render(scene, camera);

Use TextureAtlas, TextureAtlasPacker, createSpriteFromAtlas, or AssetGroupLoader packAtlas when many sprites should share one texture. In WebGL this helps reduce texture binds, and packWithStats() shows atlas occupancy.

Interaction Tools

Interaction lives in focused modules, not inside the renderer.

import { InteractionController, SelectionManager } from "raw2d";

const selection = new SelectionManager();
const interaction = new InteractionController({
  canvas: canvasElement,
  scene,
  camera,
  selection,
  onChange: () => renderer.render(scene, camera)
});

interaction.enableSelection();
interaction.enableDrag();
interaction.enableResize();

MCP And Automation

raw2d-mcp is the automation package for agents, docs generators, and project tooling. It works with scene JSON, validates unknown input, inspects renderer hints, generates Canvas/WebGL examples, and returns explicit visual-check command plans.

import {
  addRaw2DSceneObject,
  createRaw2DSceneJson,
  generateRaw2DCanvasExample,
  validateRaw2DScene
} from "raw2d-mcp";

const document = addRaw2DSceneObject({
  document: createRaw2DSceneJson(),
  object: { type: "rect", id: "card", width: 120, height: 80 }
});

const result = validateRaw2DScene({ document });
const example = generateRaw2DCanvasExample({ document });

console.log(result.valid);
console.log(example.code);

Architecture

packages/
  core/         raw2d-core
  canvas/       raw2d-canvas
  webgl/        raw2d-webgl
  sprite/       raw2d-sprite
  text/         raw2d-text
  interaction/  raw2d-interaction
  effects/      raw2d-effects
  raw2d/        umbrella package

Rules that shape the codebase:

  • TypeScript strict mode
  • no external rendering library
  • no React dependency in core packages
  • each module keeps its own *.type.ts
  • object classes do not contain Canvas/WebGL drawing logic
  • renderers own drawing
  • files stay small and focused

Local Development

npm install
npm run dev

Docs run locally at:

http://localhost:5174/doc

Examples run at http://localhost:5174/examples/canvas-basic/ and the other examples/*/ paths.

The integrated Raw2D Studio runs at http://localhost:5174/studio. It uses the same public Raw2D APIs as application code and keeps a live generated TypeScript view beside the visual scene.

Start with the Docs quick paths for a first Canvas scene, practical interaction, React components, or the Studio-to-code workflow. Code examples are visible by default and the navigation groups can be collapsed as the reference grows.

Quality checks: npm test, npm run build:docs, and npm run pack:check.

Performance Roadmap

WebGL2 renderer, batch rendering, texture atlas, object pooling, dirty matrix updates, culling, typed array buffers, and static/dynamic batches.

License And Attribution

Raw2D is licensed under the Apache License 2.0.

Copyright 2026 Aditya Nandlal

Redistributions must keep the LICENSE and NOTICE files. The Raw2D name and project identity are project marks; do not use them to imply that a fork, package, product, or service is official unless you have permission.

About

Low-level 2D rendering engine for JavaScript and TypeScript—Canvas-first and WebGL2-ready.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages