Choose one format for the same game listing. New kits detect spawnkit.config.ts or spawnkit.config.json at the project root and produce dist/spawnkit.config.json. TypeScript adds editor type checks; JSON needs no code. Keep one source file, because duplicate configurations stop the build.
import { defineConfig } from "./spawnkit/config"
export default defineConfig({
title: "Golden Dash",
description: "Collect gold and dodge obstacles in a fast arcade challenge.",
genre: "Arcade",
dimension: "2D",
coverPath: "media/cover.webp",
details: {
objective: "Collect as much gold as possible.",
controls: "Move with the arrow keys.",
devices: "Desktop keyboard"
}
})
{
"schemaVersion": 1,
"title": "Golden Dash",
"description": "Collect gold and dodge obstacles in a fast arcade challenge.",
"genre": "Arcade",
"dimension": "2D",
"coverPath": "media/cover.webp",
"details": {
"objective": "Collect as much gold as possible.",
"controls": "Move with the arrow keys.",
"devices": "Desktop keyboard"
}
}
Save the TypeScript example as spawnkit.config.ts, or the JSON alternative as spawnkit.config.json, beside package.json. Supply a real public/media/cover.webp file up to 1 MiB. To add video, set trailerPath to media/trailer.mp4 and supply that file under public/: at most 2 MiB and 60 seconds. Start on gameplay; the preview uses the beginning of the clip.
pnpm lint
pnpm build
pnpm preview
Open the preview URL. Play through movement, scoring, restart, and any audio interaction. Check the browser console and network panel. Confirm dist/index.html, dist/spawnkit.config.json, and your referenced media exist. Stop preview before packaging.
Run one of these from your game root. The Bash example needs the zip utility installed. Both examples stop if game-release.zip already exists, so an older archive cannot silently retain stale files.
if (Test-Path -LiteralPath "game-release.zip") {
throw "game-release.zip already exists; choose a new filename."
}
Compress-Archive -Path "dist/*" -DestinationPath "game-release.zip"
if [ -e game-release.zip ]; then
echo "game-release.zip already exists; choose a new filename." >&2
else
(cd dist && zip -r ../game-release.zip .)
fi
game-release.zip
├── index.html
├── assets/
├── media/cover.webp
└── spawnkit.config.json
There must be no outer dist/ directory in the archive. Keep the expanded build below 20 MiB and fewer than 1,996 files. See Publish your game for upload limits and the dashboard steps.
Open Upload game, select the archive, review the imported details and media, and deploy. This flow creates a new project. Wait for a successful result, then open the returned game URL in a fresh browser tab.
| Check | Expected result |
|---|
| First load | The game starts and required requests succeed. |
|---|
| Gameplay | Controls, scoring, and restart match your local preview. |
|---|
| Media | Cover and optional trailer appear, or the deployment reports an actionable omission warning. |
|---|
| Discovery | Listing approval is tracked separately from successful hosting. |
|---|
Keep the existing project ID. Repeatedly using the new-game upload flow creates separate projects. After @spawnkit/cli is published, link your source folder to the intended project and review the deployment plan before sending an update.
pnpm dlx @spawnkit/cli login --site https://spawnkit.cloud
pnpm dlx @spawnkit/cli link --project YOUR_PROJECT_ID
pnpm install
pnpm lint
pnpm build
pnpm dlx @spawnkit/cli deploy --env production --dry-run
pnpm dlx @spawnkit/cli deploy --env production
This source-deployment example is for a generated SpawnKit game with game.config.json and a pnpm lockfile. It does not adopt an arbitrary uploaded HTML game. It is a separate path from uploading a built ZIP. Use the CLI reference for logs, release promotion, and rollback. Until the package is published, use support for an existing-project publishing path rather than creating a duplicate.