Conway's Game of Life,
running as a service

A Go simulation core with a REST + WebSocket streaming API and a React/WebGL2 UI — all shipped in one small distroless container. State lives in SQLite, so the world survives restarts.

$ docker run -d -p 8050:8050 mist941/b3s23-engine

What's inside

A complete, production-shaped Game of Life: simulation engine, streaming API, interactive UI and persistence — with zero configuration.

Interactive editing

Draw cells with the mouse — paint, erase, toggle — or stamp classic patterns with a live ghost preview.

WebGL2 renderer

Bit-packed frames are unpacked on the GPU. Smooth pan and zoom even on large grids.

REST + WebSocket API

Full control surface — play, pause, step, reseed, resize, tick rate, cell editing — plus binary frame streaming with per-client backpressure.

Persistent

The grid is snapshotted to SQLite and restored on restart. Pause, redeploy, continue.

Compact engine

Bit-packed toroidal grid — one bit per cell, up to 16384×16384 — stepped in parallel across CPU cores.

Easy to run

One small distroless Docker image (amd64 + arm64), health check included, no configuration required.

Run it

Docker

One command. The UI and the API are served from the same port — open localhost:8050 when it's up.

# the /data volume keeps the SQLite database, so the world survives restarts docker run -d --name b3s23 -p 8050:8050 -v b3s23_data:/data mist941/b3s23-engine:latest

Docker Compose

Clone the repository, then:

docker compose up -d # pulls the published image docker compose up -d --build # or build it from source

From source

Engine (Go ≥ 1.26, no CGO) and the UI dev server (Node ≥ 24) with hot reload:

# engine — API on :8050 cd engine go run ./cmd/engined # UI dev server, proxies /api to the engine cd ui npm install npm run dev

Or build the UI once and serve it straight from the engine binary:

cd ui && npm install && npm run build cd ../engine && go run ./cmd/engined -static ../ui/dist

See it in action

B3S23 Engine demo: drawing cells, stamping patterns and streaming the live simulation

Built-in pattern library

Eight classics ship with the UI — pick one, hover for a ghost preview, click to stamp it onto the grid.

Glider

The smallest spaceship — glides diagonally forever.

Lightweight spaceship

Cruises across the grid at half the speed of light.

R-pentomino

Five cells that erupt into a thousand generations of chaos.

Acorn

Seven cells that take 5,206 generations to settle down.

Diehard

Vanishes without a trace after exactly 130 generations.

Pulsar

The best-known period-3 oscillator.

Pentadecathlon

Blinks through a fifteen-generation cycle.

Gosper glider gun

Fires a fresh glider every 30 generations — forever.

Drive it over the API

Everything the UI does goes through the public API — script it with anything that speaks HTTP. Frames stream over WebSocket at /api/v1/ws.

# current state curl localhost:8050/api/v1/status # pause the loop curl -X POST localhost:8050/api/v1/pause # draw a glider, cell by cell curl -X POST localhost:8050/api/v1/cells \ -d '{"cells":[[11,10,1],[12,11,1],[10,12,1],[11,12,1],[12,12,1]]}' # reseed the whole world at 30% density curl -X POST localhost:8050/api/v1/reseed -d '{"probability":0.3}'