Excalibur.js: a TypeScript 2D engine that publishes to npm and NuGet
🎮 Your friendly TypeScript 2D game engine for the web 🗡️
At a glance
- What is it?
- Excalibur gives you a scene graph, collision detection and a fixed update loop in the browser, under a licence that allows commercial use. It is still on version 0.x, which is the fact to weigh before you commit.
- Who is it for?
- Excalibur is a good fit for a browser 2D game written in TypeScript by someone who wants an engine rather than a framework, and a poor fit for anything needing a stable API or a 3D pipeline. The decisive number is that the package is still 0.32.0 with `exNextVersion` set to 0.33.0, and the README says outright that breaking changes will occur.
- Can I use it commercially?
- Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An engine in the npm sense, licensed for commercial games
Excalibur describes itself as a friendly TypeScript 2D game engine for the web, and its repository description is blunter about the category: a simple JavaScript game engine with TypeScript bindings for making 2D games in HTML5 canvas. That distinction between engine and framework is the one that matters when you evaluate it. An engine owns the update loop, the scene, collision and rendering. It does not ask you to reorganise your application around its component tree.
The README's stated goal is to remove boilerplate, handle cross-platform targeting, and otherwise let you use as much or as little as you need. Cross-platform targeting is not aspirational here: the project tests through BrowserStack and states a policy of supporting the latest two versions of popular desktop and mobile browsers, with a badge on the repository home page pointing at that infrastructure.
Licensing is unusually clear for a game engine. It is BSD 2-clause, the README says in as many words that this means you can use it in commercial projects, and the licence text in the repository is the standard short form: retain the copyright notice in source redistributions, reproduce it in binary redistributions, and that is the whole obligation. There is no copyleft, no per-sale revenue share and no registration step. That matters more for a game engine than for most dependencies, because engines tend to end up in shipped bundles.
The package metadata adds one detail worth knowing: publishing is configured with provenance enabled, which produces verifiable build attestations for the packages npm receives.
Getting the engine installed and running locally
The README does not give the consumer install command inline. It links to an installation guide and a getting started guide on the documentation site, which is where the actual npm instructions live. What the README does document is the contributor setup, and that setup is worth reading even if you only intend to consume the package, because it shows what the project considers its supported toolchain.
The prerequisite is Node.js at an LTS version, with the ESLint plugin for VS Code recommended. After cloning, two commands:
npm install
npx playwright install --with-depsThe Playwright step installs browsers and, with that flag, the system dependencies they need, which vary by operating system. The README offers a dev container as an alternative if you would rather not install those locally, and a `.devcontainer/` directory at the repository root backs that up. Docker or Podman is all that is required.
Contributors then work through npm scripts rather than direct tool invocations. `npm run all` runs formatting, linting, the build and the tests, and the README calls it the thing to run before finalising a pull request. `npm run build` compiles the engine alone, which is the fast check, and `npm test` runs the engine tests without recompiling. Two of the remaining scripts are unusual enough to be worth naming: `npm run sandbox` starts a Storybook-based playground used for interactive visual tests and documentation examples, and `npm run nuget -- 1.1.1` packs a NuGet package at a given version, which is the path to a C# or Unity-facing distribution.
What package.json says the engine actually is
The manifest is more informative than the marketing copy. The entry points are declared as conditional exports: the package resolves to a development build under a `development` condition and a production build under `production`, with the plain `import` condition pointing at the production file. Alongside them sit `main` at `build/esm/excalibur.min.js` and typings at `build/esm/excalibur.d.ts`, so the TypeScript definitions ship from the same build output as the JavaScript.
That conditional setup is a real feature rather than a detail. It means a bundler configured to use development conditions gets an unminified, debuggable build, and a production build in your app gets the minified one, without the application code changing. It also means a bundler that does not understand the `exports` field can fall back to `main` and get the minified file even in development, which is the kind of rough edge the 0.x warning covers.
The version fields are the more important thing. The package is at 0.32.0, and there is a separate `exNextVersion` field set to 0.33.0, which appears to be the project's own marker for the version under preparation. The README does not explain that field, so treat it as an internal bookkeeping value rather than something to plan against.
The manifest also carries `"sideEffects": false`, a hint to bundlers that the package is safe to tree-shake, which only pays off if the engine's own modules are written to tolerate being imported partially.
Version 0.x is the headline caveat, and the README says so itself
The README includes a note that is worth reading before anything else, because it is unusually direct. Excalibur is still in version 0.x, which means the project and its associated plugins may be a little rough around the edges. The project says it tries to minimise API changes, but that breaking changes will occur in new released versions.
For a game engine that is a bigger deal than for a utility library. The release cadence visible in the repository is roughly quarterly: v0.30.3 on 2025-01-02, v0.31.0 on 2025-09-26, v0.32.0 on 2025-12-23. Nine months between the first two of those, and then under three months to the next. Meanwhile the last push was on 2026-09-27, which tells you work is still landing on the branch between tagged releases.
There is a 1.0 release roadmap linked from the README, tracked as a GitHub issue, and the existence of that issue is the strongest signal about intent. It also tells you the API is still moving toward a stability commitment that has not been made yet. Plugins, which the note explicitly includes in the rough-edges warning, are the ecosystem most exposed to that churn, since a 0.x breaking change in the engine can break every plugin built against it.
One more note from the README on expectations: the project describes itself as a labour of love built from spare time, which reads as a direct statement about maintainer capacity. Plan your dependency on that basis rather than on the activity level alone.
The repository as a signal of how the project works
The top-level entries describe a well-equipped project. There is a `sandbox/` directory alongside a `.storybook/` config, which is the visual testing setup the README describes, and a `playground/` directory that is presumably for trying things quickly. Build configuration is split across `vite.config.ts` and `vite.config.common.js`, and unit tests run under `vitest.config.ts` while browser tests run under Karma through `karma.conf.browsers.js`. Two config files for Karma and Playwright tells you both fast local iteration and cross-browser verification are first-class.
There are also the files that show project governance. `SECURITY.md` and `STYLEGUIDE.md` sit at the root, `.github/` holds the contribution guidelines and code of conduct the README points to, and `renovate.json` alongside a `.husky/` directory indicates automated dependency updates and commit hooks. `CHANGELOG.md` is present, and `version.js` next to `Excalibur.nuspec` suggests versioning is scripted rather than typed by hand.
Documentation lives in `site/` inside the repository, and the README invites contributions to it directly. That is a healthy sign: the docs are versioned with the code, and the API reference the README advertises is generated from the same tree you would clone.
The `LICENSE.md` file confirms BSD 2-clause, and the licence text in the README is attributed to Erik Onarheim with a 2014 copyright date, which is when the project started. The library is published to both npm and NuGet, which tells you the maintainers expect the engine to be consumed from more than one ecosystem.
Where Excalibur stops being the right choice
Three boundaries are visible in the project's own materials. The first is 3D, which is simply absent: the engine is for 2D in HTML5 canvas, and there is nothing in the repository suggesting otherwise. A project that starts as 2D and grows into 3D will outgrow it, and the migration cost lands late.
The second is engine stability, discussed above, and it interacts with the third: team size and project longevity. A weekend game or an internal training exercise absorbs 0.x churn easily. A commercial title with a team and a schedule does not, because every breaking change becomes a coordination task rather than a code edit. The existence of the 1.0 roadmap issue means the project is aware of this, but it does not mean the problem is solved.
The realistic alternative for a browser 2D project is Phaser, which is older, more widely deployed, and at a stable version, at the cost of Phaser's own heavier conventions and its own learning curve. Native platform games are the other comparison: if the target is a mobile or desktop store rather than a browser, an engine that targets canvas in a web page is the wrong layer, and the NuGet packaging hints at an existing C# path but does not change that.
For a TypeScript developer building a 2D browser game who values a real engine over a thin wrapper, Excalibur is a legitimate choice with an honest warning attached. Read the roadmap, check the release notes against your own code, and pin the version.
Editorial conclusion
Excalibur is a good fit for a browser 2D game written in TypeScript by someone who wants an engine rather than a framework, and a poor fit for anything needing a stable API or a 3D pipeline. The decisive number is that the package is still 0.32.0 with `exNextVersion` set to 0.33.0, and the README says outright that breaking changes will occur. Start at the installation page on excaliburjs.com/docs, read the 1.0 release roadmap linked from the README, and budget for the migration work a 1.0 release implies.
Frequently asked questions
Can I use Excalibur.js in a commercial game?
Yes. The project is open source under the BSD 2-clause licence, and the README states explicitly that this means you can use it in commercial projects. The obligations are the standard short form: retain the copyright notice when redistributing source, and reproduce it when redistributing in binary form.
Is Excalibur.js stable enough for production?
The package is still at 0.32.0, and the README includes a note that the project and its plugins may be rough around the edges and that breaking changes will occur in new releases. A 1.0 release roadmap is tracked as a GitHub issue linked from the README, so stability is an announced goal rather than a current guarantee. Pin the version and read the changelog before upgrading.
What are the system requirements for building Excalibur from source?
Node.js at an LTS version is required, and the README recommends the ESLint plugin for VS Code. After cloning you run npm install followed by npx playwright install --with-deps, which pulls the browsers and the system dependencies they need. If you would rather not install those locally, the repository includes a dev container that needs only Docker or Podman.
Which browsers does Excalibur support?
The project states a policy of supporting the latest two versions of popular desktop and mobile browsers, and it enforces that through automated BrowserStack testing rather than by assertion. Contributors run the browser suite through Karma using the karma.conf.browsers.js configuration in the repository.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/excaliburjs-excalibur)