Skip to content

The Multithreaded ECS Framework for the Web

An approachable, flexible, and high-performance framework for building games, whiteboards, and more.

Easy to Use

Straightforward API for defining components, creating entities, and writing systems. Full type-safety with TypeScript.

Reactive Queries

Track all changes to entities and components automatically. Query for entities that were added, removed, or changed since the last frame.

Built-in Multithreading

Run heavy workloads in parallel without any jank. Effortlessly distribute work across multiple CPU cores, no manual thread management required.

Open Source

Read the source code, create issues, and contribute on GitHub. We welcome contributions and feedback as the project grows.

import {
addComponent,
createEntity,
defineComponent,
defineQuery,
defineSystem,
removeEntity,
field,
World,
} from '@woven-ecs/core';
// Define components with typed fields
const Particle = defineComponent({
position: field.tuple(field.float32(), 2),
velocity: field.tuple(field.float32(), 2),
color: field.tuple(field.uint8(), 4), // RGBA
life: field.float32(),
});
// Query all particles
const particles = defineQuery((q) => q.with(Particle));
// Spawn a burst of particles
function emit(ctx, x, y, count) {
for (let i = 0; i < count; i++) {
const angle = Math.random() * Math.PI * 2;
const speed = 50 + Math.random() * 100;
const eid = createEntity(ctx);
addComponent(ctx, eid, Particle, {
position: [x, y],
velocity: [Math.cos(angle) * speed, Math.sin(angle) * speed],
color: [255, 140, 50, 255],
life: 1.0,
});
}
}
// Update particles: move, fade, and destroy dead ones
const particleSystem = defineSystem((ctx) => {
const dt = ctx.time.deltaMs / 1000;
for (const eid of particles.current(ctx)) {
const p = Particle.write(ctx, eid);
p.position[0] += p.velocity[0] * dt;
p.position[1] += p.velocity[1] * dt;
p.life -= dt;
if (p.life <= 0) removeEntity(ctx, eid);
}
});
// Create the world and run
const world = new World([Particle]);
// An initial burst of particles
world.execute((ctx) => emit(ctx, 400, 300, 200));
function loop() {
world.sync();
world.execute(particleSystem);
requestAnimationFrame(loop);
}
loop();
  • Powerful Queries: Filter entities by component presence with with, without, and any operators
  • Change Tracking: Query for entities that were added, removed, or changed since last frame
  • Rich Field Types: Numbers, strings, booleans, arrays, tuples, enums, binary, and entity references
  • Singletons: First-class support for global state like time, input, and configuration
  • Multithreading: Execute systems in parallel across worker threads with automatic entity partitioning
  • Entity References: Reference other entities with automatic validation

The @woven-ecs/canvas-store and @woven-ecs/canvas-store-server packages extend Woven-ECS with everything you need to build multiplayer editor applications like infinite canvases or other creative design tools.

Real-time Sync

WebSocket-based multiplayer with conflict resolution. Multiple users can edit the same document simultaneously.

Local-First

Your app works offline by default. Data lives on the client and syncs to the server when connected.

Undo/Redo

Full history tracking with configurable depth. Support for undo/redo across multiple users with proper conflict resolution.

Persistence

Automatic IndexedDB storage for offline support. Changes are saved locally and synced when back online.

Migrations

Version your component schemas with automatic migrations. Evolve your data model without breaking existing documents.

Configurable

Configure sync behavior per component: persist to server, sync ephemerally, store locally, or skip entirely.

Learn more about canvas-store →

Woven Canvas is an open-source infinite canvas SDK. It has a plugin architecture and is very customizable. If you’re building a collaborative whiteboard or design tool, give Woven Canvas a look!

  • Quick Start - Install Woven-ECS and create your first project
  • Components - Learn about defining and using components
  • Queries - Master the query system for finding entities
  • Multithreading - Understand how to set up multithreaded systems