EX

Excalibur

TypeScript-first 2D game engine for the web

Game Engines & Frameworks ★ 2.3k stars Medium setup BSD-2-Clause

Excalibur is a free, open-source 2D game engine written in TypeScript for making browser games. Games created with Excalibur are self-hostable as static sites and run on desktop and mobile browsers.

Key features

  • TypeScript-first 2D engine
  • Self-hostable web games
  • Built-in physics and ECS
  • Cross-platform output

Pros & cons

Strengths

  • Great TypeScript support
  • Friendly to beginners

Trade-offs

  • Engine, not a game
  • 2D only

Excalibur replaces

Last reviewed Sep 13, 2026 · 775 words

You do not host Excalibur. You host what it produces: a folder of HTML, JavaScript, and image files that any static web server can serve, which is why a 2D game engine with 2,342 stars belongs on a self-hosting directory at all. Excalibur is a BSD-2-Clause TypeScript library that runs entirely in the browser, and the self-hosting question is really a build-and-serve question. The engine is easy to learn, the build is a standard Vite bundle, and the whole thing runs from a 128 MB container serving files. The part nobody tells you: the engine gives you no server side at all, so multiplayer, leaderboards, and saves that follow a player between devices are yours to build.

Where it sits in a stack

Excalibur is the game layer, and only that. It provides an Engine that owns the canvas and the game loop, Scene objects for levels or menus, and Actor objects with position, velocity, collision, sprites, and animations. There is an entity component system underneath for people who prefer that model, two physics modes (a simple arcade solver and a realistic rigid-body one), a camera with strategies for following and locking, a tilemap loader that reads Tiled and LDtk files, and audio and input handling. It draws with WebGL and falls back to 2D canvas.

What it is not: a scene editor like Godot's, a networking library, an asset pipeline, or anything that runs on a server. Compared with PixiJS, which is a renderer that expects you to write the game loop and physics yourself, Excalibur is the batteries-included choice; compared with melonJS, it has the stronger TypeScript story and, in my experience, the more approachable documentation. The wider set of options lives in the game engines category.

From npm init to a folder of static files

The maintained starting point is the official template:

npm create excalibur@latest my-game
cd my-game
npm install
npm run dev

That gives you a Vite project with TypeScript, a sample scene, and hot reload on localhost:5173. When the game is ready, npm run build writes everything to dist/, typically 1 to 5 MB depending on your art. That folder is the deliverable. There is no runtime dependency, no Node process to keep alive, and nothing that phones home.

Cross-platform output means browsers on desktop and mobile, with touch input handled through the same pointer events as the mouse. Wrapping the build in Electron or Capacitor for app stores is possible and outside the engine's scope.

Serving it is the easy part

Any static host will do, and the one I use is Caddy because a two-line site block gets you automatic TLS:

game.example.com {
    root * /srv/games/my-game/dist
    file_server
    encode gzip
}

Enable compression, because a bundled JavaScript game compresses by 60 to 70 percent. Set long cache headers on the hashed asset files that Vite emits and a short one on index.html. If you want to keep it off the public internet, the same folder behind Tailscale or inside your LAN works identically, since the game runs in the player's browser and never needs to reach a server after it loads.

Sound and WebGL both require the page to be served over HTTPS or from localhost in current browsers, so a plain http://192.168.1.10 share will play silent games. Caddy's automatic certificates or a Tailscale HTTPS cert solves that.

The missing server side is the honest limit

Excalibur games are single-player by default, and stay that way unless you build a backend. A leaderboard needs a small API and a database; persistent saves need either localStorage (per browser, per device) or an account system; real-time multiplayer needs a WebSocket server and the whole authoritative-state problem that comes with it. None of this is unusual for a browser game engine, but it is the difference between "self-hosting a game" and "self-hosting a game service". The engine does not pretend otherwise: the cons list reads "engine, not a game" for a reason.

What I'd do

Use Excalibur for a 2D game you want to ship as a URL, build it with the official template, and serve dist/ from Caddy with gzip on. Store saves in localStorage until you have players who complain about losing them, and only then add a tiny backend. If you need 3D, or an editor that artists can work in, this is not the engine, and no amount of self-hosting enthusiasm changes that.

Compare Excalibur

2 head-to-head comparisons.

Similar game engines & frameworks apps