Make. Join. Play. Repeat.
The whole point is one loop:
build something playable, get friends in fast, play it together, tweak it, and go again.
Make
Start with one command, write your game logic, and let Air Jam handle the room, controllers, and networking.
Join
Players scan a QR code or tap a link. Their phone opens the right controller in the browser with no install friction.
Play
Inputs hit the big screen in real time, the room comes alive, and the payoff happens immediately.
From Prompt to Playable
A real one-shot build in a minimal Air Jam project.
Claude Code scaffolds the game, opens preview, uses the controllers, and gets to a working result.
Built with Air Jam
Real games you can play right now.
Different genres, different controllers, same instant join.
Everything you need, out of the box
Free public server
No infra to manage. Your game connects to a hosted server automatically -- free for development and production.
Instant QR join
Every room gets a QR code and shareable link. Players join in seconds from any phone browser.
Publish to the Arcade
Ship your game to the Arcade with one command. Players discover and play it instantly.
Built-in analytics
Session counts, player metrics, and performance data from day one. No third-party setup.
Cross-device debugging
Stream logs from every connected phone and the host into one unified view.
First-class agent support
Typed agent contracts let coding agents read state and play your game to verify it works.
airjam.config.ts
One config, two surfaces
Define your input schema once. The host and every controller share the same typed contract.
The docs cover the full host, controller, and store setup.
import { createAirJamApp, env } from "@air-jam/sdk";
import { z } from "zod";
const inputSchema = z.object({
vector: z.object({ x: z.number(), y: z.number() }),
action: z.boolean(),
});
export const airjam = createAirJamApp({
runtime: env.vite(import.meta.env),
controllerPath: "/controller",
input: { schema: inputSchema },
});store.ts
Shared state that just works
Create a store on the host, read it from any phone. Actions go through the host so the source of truth stays in one place.
Full action contract and flow diagrams in the docs.
import { createAirJamStore } from "@air-jam/sdk";
export const useGameStore = createAirJamStore((set) => ({
score: 0,
actions: {
addPoint: (_ctx, { delta }) =>
set((s) => ({ score: s.score + delta })),
},
}));
const actions = useGameStore.useActions();
const score = useGameStore((s) => s.score);Who it's for
type AirJam = AirPlay & GameJam;Developers
Typed APIs, predictable networking, and a clear host/controller model you can reason about.
Tinkerers & vibe-coders
Skip the infrastructure and get to a playable room with friends in minutes.
First-time game makers
Easy to start, no ceiling when you're ready to go deeper.
And of course, for any party of players :)
Ready to build your first game?
Start with the docs, then jump into the arcade to see the kind of thing you can make.