Quick Start
Get your first Air Jam game up and running in minutes using our project generator.
You need Node.js 22 or newer and pnpm installed. The generator runs pnpm install
for you unless you explicitly choose --skip-install.
1. Create a New Project
The fastest way to start is using our CLI tool. This creates a ready-to-use workspace with a working Pong game, local development server, and SDK configuration.
npx create-airjam my-gameAfter the project is created, navigate into the directory and open it in your editor:
cd my-game
code . # or your preferred editor2. Start Local Development
The scaffold uses one command for the normal local loop. It starts the local Air Jam server and the game together.
pnpm run devThat command starts:
- the local Air Jam server on
http://localhost:4000 - the game on
http://localhost:5173
If Claude Code Desktop preview launches the app, use the committed .claude/launch.json. It still goes through the normal Air Jam dev runner, but adds the preview-managed adapter Claude Preview needs.
For other browser or agent preview tools that ask for a launch command, use pnpm run dev. Do not fall back to raw vite or a separate preview-only script.
3. Play the Game
Open your browser and visit:
You should see the Pong template game. You can now:
- Open the game in your browser (Host view)
- Scan the QR code with your phone (Controller view)
- Play the game!
Optional: HTTPS for Motion Sensors
Most local Air Jam development works on HTTP. Enable HTTPS only when you need secure browser APIs such as gyroscope or motion sensors.
- Install
mkcertonce on your machine. - Initialize secure mode:
pnpm run secure:init - Run secure dev:
pnpm run dev -- --secure
This keeps the local Air Jam server on http://localhost:4000 and serves the game over trusted local HTTPS.
Optional tunnel fallback:
pnpm exec airjam secure:init --mode=tunnel --hostname my-game-dev.example.com --tunnel my-game-dev
pnpm run dev -- --secure --secure-mode=tunnel4. Customize & Build
This project is "vibecode friendly"—it includes documentation and AI instructions to help you build faster.
- Check
AGENTS.md: Project-wide coding contract and workflow for AI coding assistants. - Check
docs/airjam/docs-index.md: Canonical local framework references bundled with the template. - Modify
src/airjam.config.ts: Canonical runtime setup and input wiring. - Modify
src/game/input.ts: Define your input schema. - Use the starter module map in the template
README.md: Follow the current starter structure before creating new homes for code. - Modify
src/game/stores/: Starter location for shared networked state and pure transitions. - Modify
src/host/index.tsx: Starter host/gameplay surface. - Modify
src/controller/index.tsx: Starter mobile controller surface. - Use
tests/game/: Starter testing pattern for domain, stores, engine, adapters, and shared game UI.
These paths are the current starter template shape. They are recommended defaults for new projects, not framework-mandated filenames.
Connect Your Coding Agent
Use your existing editor, terminal agent, or MCP client; Air Jam does not require
a separate hosted game editor. The generated project includes local instructions
and a portable .mcp.json declaration. A declaration is not the same as a client
being connected. Inspect the setup and render the configuration your client uses:
pnpm exec airjam mcp doctor --dir . --json
pnpm exec airjam mcp config --profile portable --dir .The codex and claude-desktop profiles render their respective registration
formats. Configuration rendering is read-only: install the rendered entry in
your client, then check its tool discovery. See For Agents
for semantic game control and a CLI-only path.
Run the Complete Evaluation
Before sharing a game—and again after any repair—run the canonical complete evaluation:
pnpm exec airjam evaluate --dir .It returns one machine-readable air-jam-complete-evaluation/v1 document containing the results of typecheck, lint, tests, and the production build. Agents can call the same service through the airjam.evaluate MCP action. Individual gates remain available when narrowing a failure.
Refresh Managed Framework Guidance
Scaffolded projects include an AI pack that owns canonical framework references under docs/airjam/. Top-level agent instructions and project-local skills are bootstrap files: after creation, they belong to the project and Air Jam never overwrites them.
Use these commands from your project root:
pnpm exec airjam ai-pack status --dir .
pnpm exec airjam ai-pack diff --dir .
pnpm exec airjam ai-pack update --dir .
pnpm exec airjam ai-pack repair --dir .ai-pack update consumes only the snapshot inside the installed, provenance-backed CLI package. ai-pack repair explicitly restores same-version managed drift. Both replace only AI-pack-managed framework references; neither is a merge tool or owns AGENTS.md, CLAUDE.md, project-local skills, application code, or user-created notes.
Troubleshooting
Server not connecting locally
- Verify
pnpm run devis running. - Confirm server health: http://localhost:4000/health.
- Confirm your game is using
http://localhost:4000forVITE_AIR_JAM_SERVER_URL(or no override at all for local defaults).
Local port already in use
Each parallel agent or project can run an isolated stack without stopping another one:
AIR_JAM_SERVER_PORT=4400 \
VITE_PORT=5573 \
VITE_AIR_JAM_PUBLIC_HOST=http://127.0.0.1:5573 \
pnpm run devpnpm exec airjam topology --mode=standalone-dev honors the same environment, so the CLI, semantic sessions, QR URL, Vite proxy, and local server stay on one coherent topology.
App ID errors in deployed environments
- Ensure
VITE_AIR_JAM_APP_IDis set in your host platform. - Ensure the server URL points at your real Air Jam backend.
- Re-copy the App ID from your game's dashboard settings if bootstrap fails.
QR / controller join URL issues
- Confirm host and controller are on the same room code.
- If testing on phone outside localhost, set
VITE_AIR_JAM_PUBLIC_HOST(or usepnpm run dev -- --secure). - For SPA hosting, ensure rewrites route
/controller?room=XXXXto your app entry.
5. Connect Your Game To Air Jam Services
When you're ready to share your game outside local development, first register it with Air Jam so the runtime has a stable hosted identity.
-
Create a game record:
- Go to the Platform Dashboard
- Create a game if you do not already have one
- Copy its App ID
An agent or terminal user can create the same hosted identity without navigating the dashboard after the one-time browser-assisted login:
pnpm exec airjam auth login pnpm exec airjam game create --dir . --name "My Game" --slug my-game pnpm exec airjam game inspect --game my-game -
Choose your distribution lane:
- Deploy your game to a static hosting provider like Vercel, Netlify, or GitHub Pages.
- Use that self-hosted URL for normal private review and iteration.
- If you want public Air Jam Arcade distribution, publish a hosted release artifact in step 6 below.
- For self-hosted deployments, set the following environment variables:
VITE_AIR_JAM_APP_ID=your_app_id_here VITE_AIR_JAM_SERVER_URL=https://api.airjam.io # or your own Air Jam backend
The SDK handles production bootstrap automatically from that appId. You do not need to mint tokens or add auth code in your game.
If you want to lock production bootstrap to your deployed site only, set the
optional allowed-origin list for the App ID in the dashboard settings.
Before publishing your scaffolded game, run the local checks:
pnpm test
pnpm run typecheck
pnpm run buildIf you are self-hosting the client, keep SPA rewrites enabled so /controller?room=XXXX resolves to your app entry.
Optional: Stronger Signed Host Bootstrap
If you want stricter production ownership guarantees, you can keep the game static and add one small backend or edge endpoint that returns a signed host grant.
This requires a realtime backend that verifies those grants: the hosted Air Jam
backend or your own server composed with an authService adapter. The standalone
air-jam-server command does not read AIR_JAM_HOST_GRANT_SECRET and rejects host
grants by default. Setting the secret alone does not enable grant verification.
Frontend env:
VITE_AIR_JAM_HOST_GRANT_ENDPOINT=/api/airjam/host-grantGrant issuer and verifying backend env (not the standalone server command):
AIR_JAM_HOST_GRANT_SECRET=your_signing_secretThe SDK will fetch the host grant automatically before host:bootstrap. Your game code stays unchanged.
Example endpoint shape:
import { createHostGrant } from "@air-jam/sdk/protocol";
export async function POST(request: Request) {
const { appId } = await request.json();
const { gameId, creatorId } = await loadTrustedAppIdentity(appId);
const now = Math.floor(Date.now() / 1000);
const hostGrant = await createHostGrant({
secret: process.env.AIR_JAM_HOST_GRANT_SECRET!,
claims: {
jti: crypto.randomUUID(),
aud: "airjam:realtime",
appId,
gameId,
creatorId,
iat: now,
exp: now + 60,
origins: ["https://your-game.example"],
sessionKind: "game",
},
});
return Response.json({ hostGrant });
}loadTrustedAppIdentity represents your server-side lookup; never copy game or
creator identity from the browser request. That endpoint is also where you can
add your own rules, for example checking the signed-in user or limiting which
app IDs they are allowed to bootstrap.
6. Publish A Hosted Arcade Release
The official Arcade hosting lane is now artifact-based. Self-hosted URLs are still useful for private preview, but public Arcade hosting should use a hosted release artifact.
- Run the local hosted-release preflight from your project root:
pnpm exec airjam release doctor --dir .
pnpm exec airjam release validate --dir .- Build a hosted bundle from your project root:
pnpm exec airjam release bundle --dir .That command:
- runs your build script
- bundles the static output from
dist/ - writes
.airjam/release-manifest.json - creates a hosted release zip under
.airjam/releases/<version>/
The scaffolded release:bundle script wraps airjam release bundle --dir . for you.
The hosted artifact contract is fixed:
- host entry at
/ - controller entry at
/controller
Terminal or Agent Publishing
The CLI can bundle, upload, and wait for validation using the same release services as the dashboard. Use the game slug or ID created in step 5:
pnpm exec airjam release submit --game my-game --dir . --waitThis leaves the processed release unpublished. Inspect the returned release ID, then explicitly make it live when you are ready:
pnpm exec airjam release inspect --release <release-id>
pnpm exec airjam release publish --release <release-id>
pnpm exec airjam game media --help
pnpm exec airjam game update --game my-game --arcade-visibility listedPublishing a release and listing its game are separate decisions. A processing timeout does not cancel the background job: inspect the same release rather than submitting another copy. CLI responses retain the release and generation identities needed to resume work.
Dashboard Publishing
Alternatively, upload the zip produced by airjam release bundle above:
- Go to your game's Releases page in the Dashboard.
- Upload the generated zip artifact.
- Make the validated release live.
- Upload managed thumbnail, cover, and preview media in the Dashboard.
- Set the game's Arcade visibility to listed.
Your game is now live in the public Arcade on Air Jam-hosted infrastructure.
