# PlayCanvas Engine: a browser-first 3D runtime for WebGL2, WebGPU and WebXR

> The playcanvas npm package is a JavaScript game engine that renders in the browser and ships its own ECS, physics, animation and glTF asset pipeline. It suits teams whose delivery target is a URL, not a native binary.

**playcanvas/engine** — Powerful web graphics runtime built on WebGL, WebGPU, WebXR and glTF

- Repository: https://github.com/playcanvas/engine
- Website: https://playcanvas.com
- Stars: 16,956 · Forks: 2,012
- Language: JavaScript
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/playcanvas-engine

## What PlayCanvas Engine solves, and who it is for

The problem is distribution. A studio that wants an interactive 3D scene, a game or a product configurator to open on a phone, a laptop and a headset without an install step needs a renderer that runs inside the browser, plus the surrounding machinery that a scene actually requires: a scene graph, a component model, input, audio, animation and a way to stream assets. PlayCanvas Engine packages that machinery as a single npm dependency.

The README describes it as an open-source game engine built on WebGL2 and WebGPU, for interactive 3D apps, games and visualizations that run in any browser on any device. The audience is therefore JavaScript and TypeScript developers, not artists working alone. The repository lists the PlayCanvas Editor as a separate project, so the engine is usable without the visual tool, and the README points to a guide for setting up a local development environment based on the engine.

There is a second audience worth naming. Because the engine is a library rather than an application, it can be embedded inside a larger web product: a documentation site, a storefront, a training tool. The React renderer and the web-components package in the ecosystem table exist precisely for that pattern, wrapping the same runtime in a framework-idiomatic shell.

## The entity-component architecture and the frame loop

PlayCanvas organises a scene as an entity hierarchy. An Entity is a container; behaviour and appearance arrive through components attached to it. The README's hello-world example creates a render component of type box, a camera component with a clear color, and a light component, then adds each entity to app.root. That is the whole model in miniature: entities are nodes, components are data, and systems inside the Application read them each frame.

The Application object owns the canvas and the update loop. In the example, app.on('update', dt => box.rotate(...)) subscribes to the per-frame event and receives delta time, which is how frame-rate-independent motion is written. Rendering starts with app.start(). Canvas sizing is explicit: setCanvasFillMode with FILLMODE_FILL_WINDOW and setCanvasResolution with RESOLUTION_AUTO, plus a window resize listener that calls app.resizeCanvas(). Nothing is implicit here, which is good for embedding but means you own the resize plumbing.

Assets are a separate concern. The README states the engine has an asynchronous streaming system built on glTF 2.0, with Draco and Basis compression. Scripts for game behaviour can be written in TypeScript or JavaScript, and the package ships playcanvas.d.ts, so the component APIs are typed. Physics is not built in-house: the README describes full integration with the ammo.js rigid-body engine, which is an external dependency rather than part of the core runtime.

## Installing playcanvas and rendering a first cube

The README gives two install routes. The library route is a single npm command, which adds the engine to an existing project. The scaffolding route uses create-playcanvas, which generates a full project structure instead of just the dependency.

```bash
npm install playcanvas
```

```bash
npm create playcanvas@latest
```

After installing the package, the README's usage example is a self-contained spinning cube. It imports named exports from playcanvas, creates a canvas, constructs an Application, adds a box, a camera at position (0, 0, 3) and a directional light rotated to 45 degrees on X, then rotates the box on all three axes using the delta time passed to the update event.

```js
import { Application, Color, Entity, FILLMODE_FILL_WINDOW, RESOLUTION_AUTO } from 'playcanvas';

const canvas = document.createElement('canvas');
document.body.appendChild(canvas);

const app = new Application(canvas);
app.setCanvasFillMode(FILLMODE_FILL_WINDOW);
app.setCanvasResolution(RESOLUTION_AUTO);
window.addEventListener('resize', () => app.resizeCanvas());

app.start();
```

What you should see is a lit blue-grey box on a dark background, rotating continuously. The README also links a CodePen of the same example if you would rather edit it in the browser before touching a local toolchain. Note that this snippet omits the entity creation lines for brevity; the full version in the README adds the box, camera and light entities before calling app.start().

## Gaussian splatting, WebXR and the features that carry real weight

The feature list is broad, and two entries stand out because they are unusual for a general-purpose web engine. The first is first-class support for loading and rendering 3D Gaussian Splats, with a dedicated user-manual page. The repository topics include 3d-gaussian-splatting and 3dgs, and the project showcase links a Gaussian Splat Statues demo. For teams working with photogrammetry-style captures, that means the capture format is a supported asset type rather than something bolted on through a custom shader.

The second is WebXR. The README describes built-in support for immersive AR and VR experiences via WebXR, and the topics list virtual-reality and webxr. Because the engine already runs in the browser, the XR path is a session mode rather than a separate build target, which is a meaningful simplification compared with engines that treat headsets as a distinct platform.

The rest of the list is conventional but complete: 2D and 3D graphics, state-based animation for characters and arbitrary scene properties, mouse, keyboard, touch and gamepad input, and 3D positional audio on the Web Audio API. The honest reading is that this is a full engine, not a rendering library. If you only want to draw triangles, you are taking on a scene graph, an asset system and a component model you may not need.

## Where PlayCanvas Engine is the wrong choice

The engine targets browsers. The README frames it as running in any browser on any device, and the graphics backends are WebGL2 and WebGPU. Nothing in the README describes native console, desktop or mobile-app output. A team whose shipping requirement is a PlayStation, Switch or Steam build is looking at the wrong project, and no amount of bundling changes that.

The consequence of a browser target is that your performance ceiling is set by the user's browser and GPU, not by your own build. WebGPU availability in particular is a platform question, and the README does not state a fallback policy or a browser support matrix, so the choice between the WebGL2 and WebGPU paths has to be verified against your own audience rather than assumed from the feature list.

There is also a packaging subtlety. The package.json exports map defines four conditions: development, profiler, production and default, each pointing at a different build artifact (for example build/playcanvas.dbg/src/index.js for development and build/playcanvas.js for production). A bundler that does not resolve these conditions correctly will silently pull the wrong build. The README does not document which condition a given toolchain picks, so this is something to check in your own build output rather than trust.

## How it differs from Three.js and from Unity's web export

Three.js is the obvious comparison and the difference is scope, not rendering quality. Three.js is a rendering library: you get a scene graph, materials and loaders, and you assemble the rest. PlayCanvas Engine ships the rest as part of the package: a component system, rigid-body physics through ammo.js, state-based animation, positional audio, input APIs and an asynchronous glTF asset pipeline with Draco and Basis compression. Choosing PlayCanvas means accepting its opinions about how a scene is structured; choosing Three.js means writing or sourcing those layers yourself.

Unity's WebGL export is the other comparison, and the difference is the runtime itself. Unity compiles your project into a binary payload that runs in the browser through a WebAssembly runtime. PlayCanvas Engine is JavaScript and TypeScript source that the browser executes directly, imported as an npm package and bundled like any other web dependency. That makes it far easier to mix with a React application or a custom element, which is exactly why the ecosystem table lists @playcanvas/react and @playcanvas/web-components. It also means your code is inspectable and debuggable in the browser's own tools, and there is a dedicated debug build for that purpose.

The trade-off runs the other way too. A JavaScript engine cannot match a WebAssembly runtime on raw CPU-bound simulation, and it inherits the browser's threading and memory constraints. If your scene is dominated by heavy physics or large-scale agent simulation rather than rendering, that difference matters more than the packaging convenience.

## Licence, build cost and staying current

The engine is MIT licensed, and the LICENSE file sits at the repository root. MIT permits commercial use and modification with attribution and without a copyleft obligation on your own code. That is a permissive position, but it is not legal advice: your obligations depend on how you redistribute the engine and what other dependencies you combine it with, and ammo.js is a separate project with its own terms.

The repository is not archived and the last push was on 2026-09-21, the same day as the v2.22.3 release, with v2.22.2 and v2.22.1 landing earlier in September 2026. Release cadence is therefore frequent, which cuts both ways. You get fixes quickly, and you also get a moving target. The package.json in the repository declares version 2.23.0-beta.15, so the development line runs ahead of the published stable releases.

Upgrade cost is mostly a typing and API question. The package ships playcanvas.d.ts, so a TypeScript build will surface signature changes at compile time rather than at runtime, which is the cheapest place to find them. Two things the README does not cover: there is no documented long-term support branch, and the README does not describe a rollback procedure if an upgrade breaks a shipped build. Pin your version and keep the previous one until you have exercised the new build in a browser.

## Conclusion

Adopt PlayCanvas Engine if your product ships as a web page and you want the renderer, ECS, physics and asset streaming in one MIT-licensed npm package. Do not adopt it if you need native console or desktop binaries, since the engine targets browsers through WebGL2 and WebGPU. Before committing, confirm which of the four export conditions (development, profiler, production, default) your bundler resolves, check that your target browsers support the WebGPU path you intend to rely on, and read the engine standalone guide for the local setup the README points to.

## FAQ

### Is PlayCanvas Engine free to use?

Yes. The repository is MIT licensed and the LICENSE file is at the root, which permits commercial use and modification. Note that ammo.js, the physics engine the README says PlayCanvas integrates with, is a separate project.

### How do I install PlayCanvas Engine?

The README gives two options: npm install playcanvas to add the engine to an existing project, or npm create playcanvas@latest to scaffold a complete project with the create-playcanvas CLI.

### What graphics backends does PlayCanvas Engine support?

The README describes the engine as built on WebGL2 and WebGPU, and it also supports immersive AR and VR through WebXR. The README does not publish a browser support matrix for either backend.

### Can PlayCanvas Engine render 3D Gaussian Splats?

Yes. Gaussian splatting is listed as a first-class feature for loading and rendering 3D Gaussian Splats, with a dedicated page in the user manual and a splat demo in the project showcase.

### Does PlayCanvas Engine work with React?

The ecosystem table lists @playcanvas/react as a React renderer for PlayCanvas and @playcanvas/web-components for declarative 3D via custom elements. Both sit on top of the core playcanvas package.

## Sources

- [License: MIT](https://github.com/playcanvas/engine/blob/main/LICENSE)
- [playcanvas/engine on GitHub](https://github.com/playcanvas/engine)
- [Project website](https://playcanvas.com)
- [README](https://github.com/playcanvas/engine/blob/main/README.md)
- [Releases](https://github.com/playcanvas/engine/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/playcanvas-engine
