Matter.js

~82kb min / ~25kb gz

Make objects fall, bounce, and collide with real physics in the browser.


01

See It in Action

Real physics in the browser — drag, throw, and smash objects that collide like they would in real life.

Boxes fall under gravity, bounce off walls, and pile up. Drag them with your mouse to toss them around.

Preview

02

What is Matter.js?

Matter.js is a 2D physics engine for the web. Drop a ball and it falls. Throw a box and it bounces off a wall. Stack blocks and knock them over. Matter.js handles gravity, collisions, and forces so you don't have to do the math yourself.

You give it shapes (boxes, circles, polygons), set properties like mass and bounciness, and it simulates realistic physics in real time. It includes a built-in renderer for quick prototyping, but you can also connect it to your own canvas or any rendering library.

Note: Matter.js is stable and widely used, but development has slowed — v0.20.0 (the latest release) came out in 2024 with no updates since. The 0.x version number reflects ongoing development, not instability. For projects that need active development or maximum performance, consider Rapier.

📦
Rigid Body Physics
Simulate solid objects with gravity, mass, velocity, friction, and bounciness — all handled for you.
💥
Collision Detection
Objects detect when they hit each other. You get callbacks so you can trigger effects on impact.
🔗
Constraints & Joints
Connect objects with springs, ropes, and hinges to build pendulums, chains, or ragdolls.

03

When to Use Matter.js

Use when
2D browser games with realistic physics (platformers, puzzle games)
Interactive product demos where users drag and throw objects
Playful UI elements — confetti, falling cards, bouncing notifications
Educational simulations (gravity, pendulums, collisions)
Physics-based data visualizations
Avoid when
3D physics — Matter.js is 2D only. Use Rapier or Cannon.js for 3D
Thousands of active bodies — Matter.js slows down around 500+ moving objects. Rapier (WASM-based) handles much larger simulations
Mobile games on tight performance budgets — the pure-JS engine is slower than WASM alternatives

04

How Matter.js Compares

Matter.js vs Cannon.js

Matter.js is 2D, Cannon.js is 3D — pick based on your dimension needs. Both projects have slowed in development. The cannon-es fork is the maintained version of Cannon.js, though it too hasn't seen updates since 2022.

Matter.js wins at
2D physics, simpler API, smaller bundle (~82kb vs ~150kb), built-in renderer
Cannon.js wins at
3D physics, Three.js integration, WebGL scenes
View Full Comparison →
Matter.js vs Rapier

Rapier is a Rust/WASM physics engine that handles both 2D and 3D with much better performance. Use Matter.js for simpler projects where ease of setup matters; Rapier when you need speed or scale.

Matter.js wins at
Simpler setup, better docs, pure JavaScript (no WASM complexity), built-in renderer
Rapier wins at
Much faster (WASM), 2D and 3D support, actively maintained, deterministic simulation
View Full Comparison →
Matter.js vs Planck.js

Planck.js is a JavaScript rewrite of Box2D — the physics engine used in many commercial games. Matter.js is easier to learn; Planck.js is familiar to developers who already know Box2D.

Matter.js wins at
Easier API, better documentation, built-in renderer for prototyping
Planck.js wins at
Box2D-compatible API, proven algorithms, active development (v1.4+)
View Full Comparison →

05

Get Started with Matter.js

Terminal
npm install matter-js
Terminal
yarn add matter-js
HTML
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/matter.min.js"></script>
Quick Start
import Matter from "matter-js";

const { Engine, Render, Runner, Bodies, Composite } = Matter;

// Create engine and renderer
const engine = Engine.create();
const render = Render.create({
  element: document.body,
  engine: engine
});

// Add a falling box and a static ground
const box = Bodies.rectangle(400, 200, 80, 80);
const ground = Bodies.rectangle(400, 610, 810, 60, {
  isStatic: true
});

// Composite.add is the modern way (World.add still works but is legacy)
Composite.add(engine.world, [box, ground]);

// Run the simulation
const runner = Runner.create();
Runner.run(runner, engine);
Render.run(render);

06

Related Libraries