Editor’s note: This article was last updated on 21 November 2022 to update information and add visual examples for the JavaScript and HTML game engines.
I know what you’re thinking: why on Earth would you use JavaScript to develop games? I thought the same thing when I discovered that you could use JavaScript and HTML5 to develop 3D games.
The truth is, since the introduction of the JavaScript WebGL API, modern browsers have intuitive capabilities that enable them to render more complex and sophisticated 2D and 3D graphics without relying on third-party plugins.
You could start your web game development journey with pure JavaScript, which is probably the best way to learn if you’re a beginner. But why reinvent the wheel when there are so many widely adopted game engines to choose from?
This guide will explore the top six JS/HTML5 game engines, ranked by the number of GitHub stars, and walk you through how to use them.
We’ll cover:
1. Three.js
Three.js is one of the most popular JavaScript libraries for creating and animating 3D computer graphics in a web browser using WebGL. It’s also a great tool for creating 3D games for web browsers.
Because Three.js is based on JavaScript, it’s relatively easy to add any interactivity between 3D objects and user interfaces, such as keyboard and mouse. This makes the library perfectly suitable for making 3D games on the web.
Pros
- Easy to learn: The most important advantage of Three.js — aside from its ability to perform complex rendering very well — is that it’s very easy to get started with
- Plenty of examples: Due to its popularity, there are countless examples to help you get started. Below are a few example projects that show what’s possible with Three.js:
- Large community: Three.js has 87.1k stars and 33.4k forks on GitHub. It has plenty of users and a sizable community of developers working with and creating various third-party tools and extensions for the library
- Good documentation: Robust documentation is usually a great indicator of a strong library, and Three.js has excellent docs
- Great performance: Three.js has a performance advantage over other libraries I have used
- PBR rendering: Three.js has built-in physically based rendering (PBR), which makes rendering graphics more accurate
Cons
- No rendering pipeline: This makes a lot of modern rendering techniques impossible/infeasible to implement with Three.js
- Not a game engine: Although Three.js possess the basic functionalities for creating games, it is not a game engine like PlayCanvas and Unity that provides features beyond interactivity and rendering. However, Three.js’ API can be built upon to create a game engine; an example of such is the Rogue engine
- Geared toward novices: Because the API caters to novices, many advanced features are hidden
- Lack of support: There is no built-in support for spatial indexing, making exact ray casting, or frustum culling, and collision detection is hopelessly inefficient in complex scenarios
Three.js in action
If you’re looking to delve into creating simple or complex 3D objects on the web, Three.js is the go-to library. Its top advantages include a vast community of talented users and abundant examples and resources.
Three.js is the first 3D animated library I worked with, and I’d recommend it to anyone starting out with game development.
Let’s create a simple rotating geometry to demonstrate what Three.js can do:
import * as THREE from 'js/three.module.js'; var camera, scene, renderer; var geometry, material, mesh; animate();
Create an init
function to set up everything we need to run our demo animation with Three.js:
function init() { const camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, .01, 20 ); camera.position.z = 1; const scene = new THREE.Scene(); const geometry = new THREE.BoxGeometry( 0.5, 0.5, 0.5 ); const material = new THREE.MeshNormalMaterial(); const mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); const renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); }
Next, create an animate
function to animate the object with your desired motion type:
function animate() { init(); requestAnimationFrame( animate ); mesh.rotation.x += .01; mesh.rotation.y += .02; renderer.render( scene, camera ); }
The finished result should look like this:
Refer to the repo and official documentation to learn more about Three.js.
2. Pixi.js
If you’re looking for a JS library to create rich and interactive 2D graphics with support for cross-platform applications, look no further than Pixi.js. This HTML5 creation engine enables you to develop animations and games without prior knowledge of the WebGL API.
Pros
- Fast performance: Just like Three.js, Pixi.js is very fast
- Large community: With 38.2k stars and 4.7k forks on GitHub, Pixi.js boasts a large community of users/developers
- Multiplatform support: Also like Three.js, Pixi.js supports multiple platforms, such as the web and native systems like Android, iOS, Windows, and mac
- Easy API: The API is easy for a beginner to understand
- Support for WebGL and Canvas fallback: Pixi.js uses a WebGL renderer but also supports a Canvas fallback
Cons
- Overly complex: In my experience, Three.js is much easier to get started with than Pixi.js
- Not a complete solution: Pixi.js proudly only supports renderer
Pixi.js in action
Pixi is a strong choice in most scenarios, especially if you’re creating performance-oriented 3D interactive graphics with device compatibility in mind. Pixi’s support for Canvas fallback in cases where WebGL fails is a particularly enticing feature.
Let’s build a simple demo to see Pixi.js in action. Use the following command or CDN to add Pixi.js to your project:
npm install pixi.js
Or CDN:
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js" ></script>
Create a script file and add the following code:
import * as PIXI from 'pixi.js'; const app = new PIXI.Application(); document.body.appendChild(app.view); app.loader.add('jumper', 'jumper.png').load((loader, resources) => { const bunny = new PIXI.Sprite(resources.bunny.texture); bunny.x = app.renderer.width / 2; bunny.y = app.renderer.height / 2; bunny.anchor.x = .5; bunny.anchor.y = .5; app.stage.addChild(bunny); app.ticker.add(() => { bunny.rotation += .01; }); });
The result should look something like this:
Refer to the repo and official documentation to learn more about Pixi.js.
3. Phaser
Phaser is a cross-platform game engine that enables you to create JavaScript and HTML5-based games and compile it for many platforms. For example, you might decide to compile your game to iOS, Android, and other native apps using third-party tools.
Pros
- Structurally sound: Phaser is known to have a well-designed structure
- TypeScript support: The library supports the use of TypeScript for game development
- Focus on game development: Phaser is primarily a game development engine — and a good one at that
- Large community: Although not as large as the first two libraries, Phaser has a sizable community with 33.2k stars and 6.9k forks on GitHub
- Plugins aplenty: Phaser supports a huge list of plugins. This includes the phaser-matter-collision, navmesh, phaser-input, and slick-ui plugins, to name a few
- WebGL and Canvas support: Phaser supports WebGL and has Canvas enabled as a fallback
Cons
- Build size: The build size of Phaser for desktop is quite massive
- Poor support for mobile development: Creating native mobile apps requires using Cordova or some other third-party framework
- State management: It can be somewhat difficult to get started with Phaser’s state manager
Phaser in action
Phaser is good for developing cross-platform game applications. Its support for a wide range of plugins and the large community of developers building games with Phaser make it easy to get started with the framework.
Let’s build a basic application with Phaser. First, install Phaser as a Node module or via CDN:
npm install phaser
OR:
<script src="//cdn.jsdelivr.net/npm/[email protected]/dist/phaser.min.js"></script>
Next, pass in some default configurations to your Phaser engine:
const config = { type: Phaser.AUTO, width: 800, height: 600, physics: { default: "arcade", arcade: { gravity: { y: 200 }, }, }, scene: { preload: preload, create: create, }, }; const game = new Phaser.Game(config);
Create a preload function to load in your default static files:
function preload() { this.load.setBaseURL("https://labs.phaser.io"); this.load.image("sky", "assets/skies/space3.png"); this.load.image("plane", "assets/sprites/ww2plane.png"); this.load.image("green", "assets/particles/green.png"); this.load.image("astroid", "assets/games/asteroids/asteroid1.png"); this.load.image("astroid2", "assets/games/asteroids/asteroid1.png"); this.load.image("astroid3", "assets/games/asteroids/asteroid1.png"); }
Finally, define a create
function to display your newly created game:
function create() { this.add.image(400, 300, "sky"); this.add.image(700, 300, "astroid"); this.add.image(100, 200, "astroid2"); this.add.image(400, 40, "astroid3"); const particles = this.add.particles("green"); const emitter = particles.createEmitter({ speed: 100, scale: { start: 1, end: 0 }, blendMode: "ADD", }); const plane = this.physics.add.image(400, 100, "plane"); plane.setVelocity(100, 200); plane.setBounce(1, 1); plane.setCollideWorldBounds(true); emitter.startFollow(plane); }
Refer to the repo and official documentation to learn more about Phaser.js.
4. Babylon.js
Babylon.js is a powerful, simple, open game and rendering engine packed into a friendly JavaScript framework.
Pros
- Playground: Babylon provides a Playground tool for testing things out before going into full development — and it has great documentation to boot
- Strong community support: Babylon has a forum with a large community of active developers and users that are very helpful. The framework has 18.9k stars and 3k forks on GitHub
- Up-to-date codebase: The framework enjoys a frequently updated codebase and active third-party tool development. The official repository was recently updated on 11/26/22
- PBR rendering: Support for PBR rendering support is excellent
- Vote of confidence: Babylon is used and supported by large brands such as Adobe, Microsoft, and more
- Maintenance: Bugs are often ironed out quickly
Cons
- Lack of maturity: Babylon was first released in 2013, which makes it quite young compared to many of its competitors
- Documentation: The engine lacks API documentation
- Not suitable for smaller projects
Babylon.js in action
Many large brands trust Babylon.js as their game development engine of choice. The Babylon Playground, a thriving hub of code samples, is a great tool to help you get started with the framework.
Babylon and its modules are published on npm. To install it, run the following command in your command line tool:
npm install babylonjs --save
Alternatively, you can integrate the library into your project via CDN. To do so, create an index.html
file and add the following code:
<canvas id="renderCanvas"></canvas> <script src="https://cdn.babylonjs.com/babylon.js"></script> <script src="script.js"></script>
After installation, you can start using the library by importing the global object or destructuring the scene and engine methods like so:
import * as BABYLON from 'babylonjs' // OR import { Scene, Engine } from 'babylonjs'
Next, create a script.js
file and include the following code:
const { createScene } = require('scene.js') window.addEventListener('DOMContentLoaded', function(){ const canvas = document.getElementById('renderCanvas'); const engine = new BABYLON.Engine(canvas, true); const scene = createScene(); engine.runRenderLoop(function(){ scene.render(); }); window.addEventListener('resize', function(){ engine.resize(); }); });
Create a scene.js
file and add the following code:
export function(){ const scene = new BABYLON.Scene(engine); const camera = new BABYLON.FreeCamera('camera', new BABYLON.Vector3(0, 5,-10), scene); camera.setTarget(BABYLON.Vector3.Zero()); camera.attachControl(canvas, false); const light = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0,1,0), scene); const sphere = BABYLON.Mesh.CreateSphere('sphere', 16, 2, scene); sphere.position.y = 1; const ground = BABYLON.Mesh.CreateGround('ground', 6, 6, 2, scene); return scene; }
Below is a preview of what your animation should look like:
Refer to the repo and official documentation to learn more about Babylon.js.
5. Matter.js
Matter.js is a JavaScript 2D, rigid-body physics engine for the web. Even though it’s a JavaScript physics engine, you can combine it with various packages and plugins to create interesting web games.
Pros
- Exciting features: Matter.js offers many features, such as rigid, compound, and composite bodies, stable stacking and resting, conservation of motion, and much more
Cons
- No CCD: Matter.js’s lack of continuous collision detection (CCD) causes an issue where fast-moving objects pass through other objects
Matter.js in action
Matter.js is subjectively the best library for creating simple, moving animation objects. Matter.js is a physics library that focuses more on 2D objects. However, you can combine it with third-party solutions to create dynamic games.
To get started with Matter.js in a vanilla project, download the matter.js
or matter.min.js
package file from the official GitHub repo and add it to the HTML file with the following code:
<script src="matter.js"></script>
However, if you’re using a bundler, such as Parcel, you can install the package as a Node module via npm
or yarn
using the following commands:
npm install matter-js //OR yarn add matter-js
The following is a minimal example using the built-in renderer and runner to get you started:
// module aliases const Engine = Matter.Engine; const Render = Matter.Render; const World = Matter.World; const Bodies = Matter.Bodies; // create an engine const engine = Engine.create(); // instantiating the renderer const render = Render.create({ element: document.body, engine: engine, options: { wireframes: false, showAngleIndicator: false, background: "white", }, }); // create two boxes and a ground const boxA = Bodies.rectangle(300, 300, 70, 70); const boxB = Bodies.rectangle(400, 10, 60, 60); const ground = Bodies.rectangle(300, 510, 910, 10, { isStatic: true }); // add all bodies to the world World.add(engine.world, [boxA, boxB, ground]); // run the engine Matter.Runner.run(engine); // run the renderer Render.run(render);
Include the above script in a page that has Matter.js installed, and then open the page in your browser. Ensure the script is at the bottom of the page (or called on the window load event or after the DOM is ready).
You should see two rectangular bodies fall and then hit each other as they land on the ground. If you don’t, check the browser console to see if there are any errors:
Refer to the repo and official documentation to learn more about Matter.js.
6. PlayCanvas
PlayCanvas uses HTML5 and WebGL to run games and other interactive 3D content in any mobile or desktop browser. Though it’s free and open sourced, PlayCanvas focuses more on the game engine than the rendering engine. Therefore, it’s more suitable for creating
3D games that use WebGL and HTML5 Canvas.
Pros
- Game engine: Unlike the rest, PlayCanvas is a game engine with features you wouldn’t otherwise find in a library or framework
- Open-source: PlayCanvas is an open source tool for powerful game development
- Mobile-optimized: The game development platform is mobile-first
- Zero compile time: The engine’s zero compiled time naturally makes the process faster
- Asset pipeline: PlayCanvas uses best practices to allow you to decide how your content is delivered and in what form
- Integrated physics engine: You can integrate physics into your game rather easily using the powerful bullet physics engine ammo.js
- Hot reloading: You don’t have to reload your browser each time you make changes
- Rendering engines only on browsers: PlayCanvas has advanced WebGL features that run only on browsers
Cons
- Private projects paywalled: The free tier does not support private projects, so all code and assets are hosted publicly
- Collision offset: There is no collision offset
- Lack of examples: Tutorials for PlayCanvas are few and far between
PlayCanvas in action
PlayCanvas is great for creating small public projects or school projects — at least, that’s what I’ve used it for. If you need more features and more control over your game development, you might want to consider subscribing for premium features.
For now, let’s do some basic rendering with the engine. As a first step, download the package file from the GitHub repository and add it to your project using the following code:
<script src='https://code.playcanvas.com/playcanvas-stable.min.js'>
Next, create a script.js
file and link it to the HTML file using the following code:
<canvas id='canvas'></canvas> <script src='/script.js'>
Now, open the script.js
file and add the following code to instantiate a new PlayCanvas application:
const canvas = document.getElementById('canvas'); const app = new pc.Application(canvas); window.addEventListener('resize', () => app.resizeCanvas()); const box = new pc.Entity('cube'); box.addComponent('model', { type: 'box' }); app.root.addChild(box);
To create the camera and light for the object, add the following codes:
const camera = new pc.Entity('camera'); camera.addComponent('camera', { clearColor: new pc.Color(.1, .1, .1) }); app.root.addChild(camera); camera.setPosition(0, 0, 3); const light = new pc.Entity('light'); light.addComponent('light'); app.root.addChild(light); light.setEulerAngles(46, 0, 0); app.on('update', dt => box.rotate(10 * dt, 20 * dt, 30 * dt)); app.start();
The code above should produce the following result:
Refer to the repo and official documentation to learn more about PlayCanvas.
Final thoughts
By breaking down the pros, cons, and use cases associated with each JS/HTML5 game engine listed above, I hope you gained some insight into which one best suits the type of game or animation you want to create.
In most cases, I would recommend using Three.js, especially if you’re looking for more of a rendering engine than a game engine. Due to its popularity in the developer ecosystem, it’ll be easy to find ample resources to help get you up and running.
If your focus is more on game development, I would suggest Babylon.js because of its simplicity. Babylon also has an updated codebase and active third-party development, and the playground feature is a great tool for testing. PlayCanvas is a solid backup option — it’s primarily a game engine, and you can use it to build complex 3D games.
What game engine do you use in your game development projects? Let us know in the comments!
LogRocket: Debug JavaScript errors more easily by understanding the context
Debugging code is always a tedious task. But the more you understand your errors the easier it is to fix them.
LogRocket allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to find out exactly what the user did that led to an error.

LogRocket records console logs, page load times, stacktraces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!
Try it for free.
Nice!
Check out the lib I made. It combines Phaser and Three.js and adds 3D physics to it.
(I plan to support PixiJS as well in the future.)
It is called enable3d.io 🙂
Oh wow, such a great one, I have checked it out, I will see how I could build with it.
I’ve used Isogenic Game Engine (IGE) a few times.
It’s a 2.5d engine with scenegraph-based rendering pipeline and a ton of other features.
Free and open source irrelon/ige on github
Just checked it out, Nice
First you say
“Since Three.js is based on JavaScript, it’s relatively easy to add any interactivity between 3D objects and user interfaces, such as keyboard and mouse. This makes the library perfectly suitable for making 3D games on the web.”
Then you say
“Cons – Not a game engine: If you’re looking for features beyond rendering – you won’t find many here”
Which is it then lol
I made the friGame engine, back in 2011, you can check it out here:
http://frigame.org/
It’s very mature and stable, as it has nearly 10 years of development behind it.
It focuses on compatibility (it’s the only engine that I know of that still supports IE6, other than gameQuery), without sacrificing speed or features.
It’s geared towards 2D games, and all the Cownado ( http://cownado.com ) games are built using friGame.
You can make a text game with plain html, a visual novel or click adventure with just html and graphics, etc. Three.js could make a simple game like this, but with no support for collision detection, it can’t even make pong.
It can, collision detection logic can be created by you, just need some mathematical formulas calculating distance between objects.
I created a ping-pong game with Pygame(2d game engine) which is base on Python.Most of the hardwork was done by me because Pygame lacks alot of features.
Collision Detection can varies with objects like circle, squares or point(Xaxis and Yaxis)
But the Formula you used depends on the game world(2d or 3d).
distance = √(x2-x1)² + (y2 – y1)²
X2 – object A “x” position
X1 – object B “x” position
Y2 – object A “y” position
Y1 – object B “x” position
This will work in a 2d game but haven’t tried it on a 3d game.I used Threejs but It is better of for animations.
3d games are based on X, Y and Z axis.
so the formula should become
distance =
√(x2 – x1)² + (y2 – y1)² + (z2 – z1)²
This Formula for the 3d detection hasn’t be tried by me but I saw it in a text book that has to do with Vectors.This Formula will work when you calculating distances between Points. Other Programmers I know tend to draw a shape around each object and apply a detection formula to it.