Turn-based & board games, made and played in seconds.

Play original games from indie makers — or ship your own. Openturn is the open source framework for turn-based and board games, with a free cloud to host them.

Just open the link

Sign in once, then any game opens straight in your browser — no install, no app store.

Bring your friends

Spin up a private room and share the link. Once your friends sign in, they're at the table.

Always something new

Independent makers ship original turn-based games here every week. Try one tonight.

  For makers

Built on Openturn.

Openturn is an open source framework for turn-based and board games — write the rules in TypeScript, run openturn deploy, and your game is live on Openturn's marketplace.

openturn cli
# Create a new game folder
$ openturn create my-game

Created local Openturn project at /Users/you/projects/my-game

Next steps:
  cd my-game
  bun install
  bun run dev

# Local dev — bun run dev runs openturn dev .
$ bun run dev

  ▶ Play URL:  http://localhost:3000/play/dev

# Deploy (after openturn login --token …)
$ openturn deploy .

Deploying . to https://openturn.io…
Deployment ID: dep_7f3a9c2e1b8d4f6a0e5c3b9d7f1a2e4c
Project ID:    prj_8a1b3c5d7e9f0a2b4c6d8e0f2a4b6c8d
Game URL:      https://openturn.io/games/you/my-game
Play URL:      https://openturn.io/games/you/my-game/play/dep_xx
Dashboard:     https://openturn.io/dashboard/projects/prj_xx
  Why ship on Openturn

A framework that handles the boring parts.

Write the rules. Skip the rest. Openturn ships the runtime, the multiplayer transport, the replays, and the deploy step — so you can spend your weekend on the game, not the plumbing.

One game, every surface

Author the rules once with defineGame. The same value powers a local React app, a CLI, hosted multiplayer, replays, and the inspector — no per-surface rewires.

Zero infrastructure

openturn deploy ships your game to Cloudflare Workers and Durable Objects. No servers to provision, no databases to run, no auth to wire — Openturn handles it.

Server-authoritative by default

Rules execute on the server. Illegal moves are rejected before they touch state, and views.player ensures opponents never receive secrets they shouldn't see.

Deterministic replays

Every match emits a JSON action log. Re-dispatch it and you get the exact same state, every time. Scrub through frames in the built-in inspector while debugging.

Plug-and-play AI bots

Drop a decide function into any seat — random, heuristic, or MCTS. The runner handles transports, so the same bot runs locally and over the network unchanged.

Persistent player profiles

Card collections, unlocks, currency, and meta-progression survive between matches — keyed per (user, game), with a pure commit() that's replay-safe and crash-recoverable.

Hidden information, handled

Model fog-of-war, hands of cards, or sealed bids inside G — then project per-seat with views.player. The engine guarantees opponents only ever see their own slice.

Plain TypeScript, no DSL

Your game is a value, not a config file. Use any types, any libs, any patterns — and get full type-safety from setup() through every move and view.

Instant local dev loop

openturn create scaffolds a project in seconds. bun run dev gives you hot reload, an iframe shell with the same bridge as production, and a play URL you can open immediately.

  Single source of truth

Write your game logic once. Run it everywhere turns make sense.

The same defineGame(...) value drives single-player and multiplayer, dev and prod, browser and CLI. Switching surfaces never means touching the rules.

export const game = defineGame({...})

Local React app

Pure in-process reducer. Zero config.

Hosted multiplayer

Durable Object per room. Auto-scaled.

Replays & inspector

Same JSON log. Scrub any frame.

AI bots

Same decide() function, any seat.

Your next game night could be shipped tonight.

Free to start. Open source on GitHub. Deploy when you're ready — there's no platform lock-in.