Ammo.js
~1.9 MB asm.jsFull 3D physics in the browser — soft bodies, vehicles, and everything the Bullet engine can do.
See It in Action
Full 3D physics simulation — objects that fall, collide, and tumble with real mass and momentum.
Boxes with real mass fall onto a ground plane, collide, and pile up — basic 3D rigid body physics.
What is Ammo.js?
Ammo.js brings the Bullet physics engine to the browser. Bullet is the same physics engine used in Grand Theft Auto, Red Dead Redemption, and many AAA games — Ammo.js lets you use that same simulation power in a web page.
Unlike simpler physics libraries, Ammo.js supports soft bodies (cloth, ropes, jelly), vehicle physics (cars with suspension and steering), and the full Bullet feature set. The trade-off is size (~1.9 MB) and a verbose, C++-style API.
When to Use Ammo.js
How Ammo.js Compares
Ammo.js has far more features (soft body, vehicles, Bullet compatibility) but is harder to learn. Cannon.js is lighter and has a cleaner JavaScript API.
Rapier is the modern choice — faster, smaller, better API. Ammo.js wins only if you need soft body physics or Bullet-specific features.
Completely different scope. Ammo.js is for 3D physics, Matter.js is for 2D physics. Choose based on dimension.
Get Started with Ammo.js
npm install ammo.js
yarn add ammo.js
<script src="https://cdn.jsdelivr.net/gh/kripken/ammo.js@main/builds/ammo.js"></script>
// Ammo.js must be initialized before use
Ammo().then(function(Ammo) {
// Create physics world
const collisionConfig = new Ammo.btDefaultCollisionConfiguration();
const dispatcher = new Ammo.btCollisionDispatcher(collisionConfig);
const broadphase = new Ammo.btDbvtBroadphase();
const solver = new Ammo.btSequentialImpulseConstraintSolver();
const world = new Ammo.btDiscreteDynamicsWorld(
dispatcher, broadphase, solver, collisionConfig
);
world.setGravity(new Ammo.btVector3(0, -9.82, 0));
// Create a rigid body (box)
const boxShape = new Ammo.btBoxShape(new Ammo.btVector3(0.5, 0.5, 0.5));
const transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(0, 10, 0));
const mass = 1;
const localInertia = new Ammo.btVector3(0, 0, 0);
boxShape.calculateLocalInertia(mass, localInertia);
const motionState = new Ammo.btDefaultMotionState(transform);
const rbInfo = new Ammo.btRigidBodyConstructionInfo(
mass, motionState, boxShape, localInertia
);
const body = new Ammo.btRigidBody(rbInfo);
world.addRigidBody(body);
// Step the simulation
world.stepSimulation(1 / 60, 10);
});