How to Destroy and Clean Up a Matter.js World

Properly cleaning up a Matter.js instance requires stopping active update loops, clearing internal simulation arrays, removing rendered DOM elements, and dereferencing all related objects to allow the JavaScript garbage collector to free memory. Failing to complete each of these steps can leave background loops running, orphan event listeners, and cause significant memory leaks in single-page applications or games.

1. Stop the Engine and Runner Loops

Before removing objects, halt the simulation updates to prevent the engine from processing new physics steps. If you are using Matter.Runner, call the stop method.

Matter.Runner.stop(runner);

If you manage your own update loop with window.requestAnimationFrame, cancel the active frame request using cancelAnimationFrame(animationFrameId).

2. Stop and Remove the Renderer

If you are using the built-in Matter.Render module, stop the rendering loop and remove the canvas from the DOM.

Matter.Render.stop(render);
if (render.canvas) {
    render.canvas.remove();
}

3. Clear Bodies and Constraints from the World

Clear the composite hierarchy to detach all rigid bodies, constraints, and sub-composites from the world instance.

Matter.Composite.clear(engine.world, false, true);

The arguments signify:

4. Clear the Engine

Invoke Matter.Engine.clear to reset the engine's internal broadphase pairs, collision registries, and state trees.

Matter.Engine.clear(engine);

5. Detach Event Listeners and Mouse Controls

If you attached a Matter.MouseConstraint, remove its DOM event listeners:

if (mouseConstraint) {
    Matter.Events.off(mouseConstraint);
    Matter.World.remove(engine.world, mouseConstraint);
}

Similarly, remove any custom event hooks bound to the engine, runner, or world using Matter.Events.off:

Matter.Events.off(engine);
Matter.Events.off(runner);
Matter.Events.off(render);

6. Dereference Variables for Garbage Collection

JavaScript's garbage collector cannot free memory if references to the objects remain in scope. Set all references to null to complete the teardown.

function destroyMatterInstance() {
    // 1. Stop execution
    Matter.Runner.stop(runner);
    Matter.Render.stop(render);

    // 2. Remove DOM elements
    if (render.canvas) {
        render.canvas.remove();
    }

    // 3. Clear listeners
    Matter.Events.off(engine);
    Matter.Events.off(runner);
    Matter.Events.off(render);

    // 4. Clear physics structures
    Matter.Composite.clear(engine.world, false, true);
    Matter.Engine.clear(engine);

    // 5. Dereference for Garbage Collector
    render.canvas = null;
    render.context = null;
    render.textures = {};
    
    render = null;
    runner = null;
    engine = null;
}