Skip to content

Build games the way you build
web apps.

CarverJS is a React engine for 2D and 3D games on the web. Three.js under the hood, components and hooks on top, P2P multiplayer wired in. Ship to a URL, not a store.

Try in playground
Go to Documentation(opens in a new tab)
GitHub stars
3.2k
live games shipped
180
engine size, gzipped
12 kB
no server required
P2P
preview60 fps5 entities
// auto-edited as you click ↑
import { Game, World, Actor } from "@carverjs/core/components";

export default function Demo() {
  return (
    <Game mode="2d">
      <World>
        <Actor type="primitive" shape="box" />
        <Actor type="primitive" shape="sphere" />
        <Actor type="primitive" shape="cone" />
        <Actor type="primitive" shape="cylinder" />
        <Actor type="primitive" shape="ring" />
      </World>
    </Game>
  );
}

Everything a game needs.
Nothing a React dev hasn’t seen.

seven proofs · scroll to advance

Declarative
scene graph.

Three components, one tree. <Game>, <World>, and <Actor>— the same JSX you’d write for a web app, only it renders to WebGL.

components docs(opens in a new tab)
tsx
import { Game, World, Actor } from "@carverjs/core/components";
 
export default function MyGame() {
return (
<Game mode="3d">
<World physics={{ gravity: [0, -9.81, 0] }}>
<Actor type="primitive" shape="box" position={[0, 5, 0]} />
<Actor type="primitive" shape="sphere" position={[2, 3, 0]} />
</World>
</Game>
);
}

Hooks for
everything.

Thirteen hooks. One per system. They read from the singleton managers <Game> already mounted, so you can call them from any component in the tree.

hooks docs(opens in a new tab)
  • useGameLoopper-frame callback, priority + timestep
  • useInputkeyboard and pointer state per frame
  • useAudiosounds, music, channels, sprites
  • usePhysicsrapier rigid body, impulses + teleport
  • useCollisionaabb / sphere / circle overlap
  • useGridCollisiontile-based grid, o(1) lookups
  • useCamerashake, smooth transitions, look-at
  • useAnimationgltf / glb playback + crossfade
  • useTweenproperty tweening + timeline
  • useParticlesgpu-instanced particle control
  • useScenescene navigation and status
  • useAssetssynchronous access to preloaded cache
  • useAssetProgressloading progress, no suspense

hover to slow · all 13 included

Rapier
built in.

One prop on <World>, one prop on <Actor>, usePhysics() for impulses. Real rigid bodies, not faked.

usePhysics docs(opens in a new tab)
click anywhere to spawn

Spatial and pitched.

Five channels (sfx · music · ui · ambient · voice), audio sprites, format negotiation, max-instances steal. Web Audio API by default, HTML5 fallback when needed.

hover or press space
pan ←/→ via xpitch ±400¢ via x
useAudio docs(opens in a new tab)

Inspect like
a webpage.

It’s React. React DevTools sees every Actor, every prop, every state. HMR hot-swaps a controller without losing physics state. The JSX is the engine.

works in chrome · firefox · edge · safari

Three.js
polished.

WebGL2 today, WebGPU when it’s ready. PBR materials, post-processing, GPU-instanced sprites, tilemap layers, and 2D and 3D in the same React tree.

rendering docs(opens in a new tab)
  • WebGL2shipping
  • WebGPUwhen ready
  • PBR materialsshipping
  • Post-processingshipping
  • Instanced spritesshipping
  • Tilemap layersshipping
  • 2D + 3Dsame tree
two canvases · one react tree · same engine

Plays well
with others.

Drop into Vite, Next.js, or Remix. Share state with Zustand, fetch with TanStack Query, persist with Yjs, layer on tone.js or ammo.js when you need them. CarverJS doesn’t replace your toolchain. It joins it.

because it’s just react · move your mouse

P2P that’s actually peer-to-peer.

WebRTC mesh, signaling free out of the box, three sync modes, automatic host migration. Zero game servers.

you·0xA1HOST0ms
host · 20hz broadcast3.2 kb/s
alex·0xB238ms
client · interpolates 20hz snapshots3.0 kb/s
ren·0xC372ms
client · interpolates 20hz snapshots3.0 kb/s
nori·0xD451ms
client · interpolates 20hz snapshots3.0 kb/s
kit·0xE595ms
client · interpolates 20hz snapshots3.0 kb/s
no game server

WebRTC data channels peer-to-peer. STUN finds, TURN relays only when NAT bites.

free signaling

Public MQTT brokers by default, zero config. Swap to Firebase RTDB if you'd rather BYO.

three sync modes

Events for turn-based, snapshot for casual, prediction with rollback for competitive.

auto host migration

Host drops, new host elected in under 2 seconds, full snapshot replay, no game data lost.

click any window · hover for detail · drag the latency slider · kick the host

Made in Carver.

Top games this week.

demo bay
running
now booting
Forest Runby @nina
pre-launch

get on the list.

we send signal when the cabinet boots and when each batch of games drops. four touches, then we stop.

one confirm · four touches · then quiet