How to Create a Motorized Joint in Matter.js

Matter.js does not provide a native "motor" constraint out of the box like some other physics engines, but you can easily simulate one by combining a standard pin constraint with an engine update event. By pinning a dynamic body to a static anchor or another dynamic body using Constraint.create and continuously manipulating its angular velocity or torque within the beforeUpdate cycle, you can achieve smooth, controllable motorized rotation.

1. Set Up the Bodies

To build a motorized joint, you first need two bodies: an anchor point and a rotating body. The anchor can be a static body pinned in space or another moving body, while the rotating body acts as the rotor or wheel.

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

// Create the engine and renderer
const engine = Engine.create();
const world = engine.world;

// Anchor body (fixed in place)
const anchor = Bodies.circle(400, 300, 10, {
    isStatic: true,
    render: { visible: false }
});

// Rotating body (the arm or wheel)
const arm = Bodies.rectangle(400, 300, 200, 20, {
    collisionFilter: { group: -1 } // Optional: prevents self-collision if needed
});

Composite.add(world, [anchor, arm]);

2. Connect the Bodies with a Pin Constraint

Next, connect the two bodies using a constraint with a length of 0 and a stiffness of 1. This acts as a standard revolute hinge.

const motorJoint = Constraint.create({
    bodyA: anchor,
    bodyB: arm,
    pointA: { x: 0, y: 0 },
    pointB: { x: 0, y: 0 }, // Pivot at the center of the arm
    stiffness: 1,
    length: 0
});

Composite.add(world, motorJoint);

3. Drive the Motor with an Update Loop

Because Matter.js does not calculate motor resistance automatically, the most stable way to drive the joint is by enforcing an angular velocity on the rotating body before every physics engine step. Listen to the beforeUpdate event on the engine:

const motorSpeed = 0.05; // Desired angular velocity in radians per step

Events.on(engine, 'beforeUpdate', () => {
    Body.setAngularVelocity(arm, motorSpeed);
});

Using Body.setAngularVelocity creates an infinite-torque motor that moves at a constant speed regardless of external forces.

4. Alternative: Torque-Based Motor

If your simulation requires realistic resistance where heavy loads can slow down or stall the motor, apply torque rather than directly overriding angular velocity:

const targetTorque = 0.02;

Events.on(engine, 'beforeUpdate', () => {
    arm.torque = targetTorque;
});

This method allows collisions and heavy external masses to push back against the motorized joint naturally.