TypeScript-first · AI-agent-ready · MIT

Game to
Website.

The framework for shipping web games.

g2w is a TypeScript-first framework for building and shipping HTML5 games — 2D first with 3D planned — for desktop and mobile web browsers. A renderer-agnostic core, an Effect-native lifecycle, and browser adapters you compose yourself.

$ pnpm create g2w my-game

// the @g2w/* packages are not yet published to npm — resolved from packed tarballs until the release lands

01 · Why g2w

A shared core to build games on

Small packages with one strict rule, enforced by architecture tests:@g2w/core never depends on a rendering technology.

F—01

Renderer Agnostic

Game code targets the renderer contract in @g2w/core, never PixiJS. WebGL today; Canvas and WebGPU backends browser-verified; a Three.js adapter planned — the core never knows.

F—02

Effect-Native Lifecycle

G2WGame orchestrates init, ownership, and idempotent shutdown through one managed Effect runtime. LIFO finalizers release every resource — the frame loop stays synchronous.

F—03

Input, Everywhere

Keyboard, pointer, and multi-touch ride one DOM-free InputState; gamepads sample through the Gamepad API adapter. Edge states reset at exactly one boundary per frame.

F—04

Scenes & Sprites

A renderer-agnostic SceneManager with explicit transition semantics, plus Transform2D/Sprite2D models with anchors and z-order — mutate the model, call sync().

F—05

Ownership-Explicit Audio

AudioManager in core, Web Audio backend in the adapter. Tracked playbacks, autoplay-aware resume(), and sounds that stay caller-owned so they can be shared freely.

F—06

AI-Agent Ready

A deterministic, DOM-free core designed to be driven by agents: injected schedulers and fakes everywhere, honest docs, and a read-only devtools overlay for live inspection.

8+
Packages
453
Tests passing
0
Runtime deps in core
2D → 3D
Renderer roadmap
02 · Packages

One framework, small packages

Compose only what your game needs. Adapters depend on core — never the reverse.

PackageResponsibilityStatus
@g2w/coreRenderer-agnostic engine contracts, Game runtime, SceneManager, InputState, GamepadState, AssetManager, sprites, audio contract — zero runtime dependencies.Done
@g2w/runtimeEffect-based application lifecycle: G2WGame, one managed runtime, LIFO finalizers, idempotent shutdown.Done
@g2w/renderer-pixiPixiJS 8 adapter: WebGL / Canvas / WebGPU backends, sprite views, texture asset loading.Done
@g2w/input-domDOM adapter: keyboard, pointer, and multi-touch through Pointer Events onto InputState.Done
@g2w/input-gamepadGamepad API adapter with an injectable polling source; the host drives poll() once per frame.Done
@g2w/audio-webWeb Audio backend: decode, playback, AudioContext ownership, autoplay resume().Done
@g2w/devtoolsRead-only dev overlay: scene explorer, transforms, FPS, watched input, runtime logs. Dev-only.Done
create-g2wZero-dependency CLI that scaffolds a TypeScript + Vite game project from a template.Done
@g2w/renderer-threePlanned 3D rendering adapter proving the renderer contract generalizes.Planned · R8
03 · Minimal usage

A game is a composition of small packages

Build a G2WGame from @g2w/runtime with a renderer, a SceneManager, input, audio, and assets — then register your resources as finalizers and let the Effect runtime own the lifecycle.

main.tsg2w · minimal usage
import { SceneManager, InputState, Sprite2D, Transform2D } from "@g2w/core";
import { DomInput } from "@g2w/input-dom";
import { PixiRenderer, createSpriteView } from "@g2w/renderer-pixi";
import { G2WGame } from "@g2w/runtime";

// a renderer-agnostic sprite: game code mutates the model only
const logo = new Sprite2D({ texture, transform: new Transform2D({ x: 16, y: 32) });
const logoView = createSpriteView({ sprite: logo, renderer });

const game = new G2WGame({
  renderer,
  canvas: document.querySelector("#game")!,
  width: 640, height: 360,
  onUpdate: (deltaTime) => {
    scenes.update(deltaTime);
    input.endFrame(); // one boundary per frame, after every consumer
  },
});

await game.init();
game.addFinalizer(() => scenes.dispose()); // LIFO disposal
game.start();
StatusHonest status: the @g2w/* packages arenot published to npm yet. Until the release lands,pnpm create g2w works only after publishing — generated projects resolve packages from packed tarballs. 2D rendering over WebGL is done and browser-verified; 3D is exploratory (Roadmap R8).

Start building with g2w

Scaffold a working TypeScript + Vite 2D game that boots through the public g2w API.