Skip to content

2D · TypeScript · Free download

PixiJS game starter

Fast 2D graphics for sprite-based games, with freedom to choose your game systems.

Build locally with your preferred editor or AI coding agent. You keep the source and choose where to publish.

No account needed. Extract into a new folder to keep your existing projects safe.

PixiJS starter illustration

What you can build

Sprite-based browser games. The starter includes a minimal movement and collection scene so you can verify the runtime before adding your own rules, artwork and levels.

Included in this kit

  • PixiJS for 2D rendering
  • Plain movement without a separate physics integration
  • HTML/CSS interface, keyboard input and editable game logic
  • Vite development server, TypeScript, linting and Vitest checks

Browser games are the supported target. Native desktop and mobile packaging are not included.

Run your game

Requires Node.js >=24.0.0 and pnpm@12.10.1.

  1. Download and extract the kit into a new folder.
  2. Open that folder in your editor and run pnpm install.
  3. Run pnpm dev and open the address shown in your terminal.

The local HTTPS setup may ask you to trust its development certificate. See the included README for setup and troubleshooting.

Run pnpm build to prepare a release. Explore hosting when you are ready to share it.

Preview the generated project

These 32 files and commands come from the same configuration used by the download.

Project files
  • dev-domains.config.mjs
  • scripts/local-environment.mjs
  • scripts/local-environment.d.mts
  • .gitignore
  • .npmrc
  • pnpm-workspace.yaml
  • tsconfig.json
  • .oxlintrc.json
  • .oxfmtrc.json
  • src/score.ts
  • src/input.ts
  • vite.config.ts
  • spawnkit/config.ts
  • spawnkit/vite.ts
  • src/style.css
  • src/main.ts
  • src/simulation.ts
  • vitest.config.ts
  • src/score.test.ts
  • src/simulation.test.ts
  • src/ui.ts
  • src/input.test.ts
  • src/main.test.ts
  • src/ui.test.ts
  • package.json
  • game.config.json
  • spawnkit.config.ts
  • public/spawnkit-listing.schema.json
  • public/media/cover.svg
  • index.html
  • README.md
  • .spawn/state.json
Available commands
pnpm dev
dev-domains run app
pnpm build
tsc --noEmit && vite build
pnpm preview
vite preview
pnpm lint
oxlint --no-ignore src vite.config.ts
pnpm test
vitest run --coverage
Entry point: src/main.ts
import { createUI } from "./ui"
import { Application, Graphics } from "pixi.js"
import "./style.css"
import { advanceScore } from "./score"
import { createSimulation } from "./simulation"
import { createInput } from "./input"

const simulation = createSimulation({ x: 400, y: 280, speed: 250, minX: 14, maxX: 786, minY: 14, maxY: 546 })

const app = new Application()
await app.init({ width: 800, height: 560, background: "#101e29", preference: "webgl", antialias: true })
app.canvas.tabIndex = 0
app.canvas.setAttribute("aria-label", "Game. Use arrow keys to collect gold.")
document.querySelector("#game")?.append(app.canvas)
const controls = createInput(app.canvas)
const player = new Graphics().roundRect(-14, -14, 28, 28, 5).fill(0xb5f46a)
player.position.set(400, 280)
const collectible = new Graphics().circle(0, 0, 11).fill(0xffc77a)
collectible.position.set(580, 280)
app.stage.addChild(player, collectible)
const ui = createUI()
window.addEventListener("pagehide", () => ui.dispose(), { once: true })
let score = 0
app.ticker.add((ticker) => {
  if (ui.isPaused()) return
  const position = simulation.step(controls.read(), ticker.deltaMS / 1000)
  player.position.set(position.x, position.y)
  if (Math.hypot(player.x - collectible.x, player.y - collectible.y) < 28) {
    score = advanceScore(score)
    const label = document.querySelector("#score")
    if (label) label.textContent = "Collected: " + score
    collectible.position.set(35 + Math.random() * 730, 70 + Math.random() * 455)
  }
})

window.addEventListener("pagehide", () => app.destroy(true, { children: true }), { once: true })

Explore other engines