How to Completely Destroy a Matter.js World

Completely destroying a Matter.js world requires halting all active simulation loops, clearing the physics composites, detaching the canvas renderer, and nullifying references to prevent memory leaks. Failing to properly dispose of these components leaves lingering requestAnimationFrame loops and uncollected physics bodies in memory. This guide details the exact steps and code required to cleanly dismantle an entire Matter.js instance.

1. Stop the Runner

The runner drives the physics engine updates. If you do not stop it, the loop will continue to process empty cycles or throw errors once bodies are removed.

Matter.Runner.stop(runner);

If you are using custom update loops via requestAnimationFrame instead of Matter.Runner, make sure to call cancelAnimationFrame(animationFrameId).

2. Stop and Remove the Renderer

If you are using Matter.Render, you must halt its internal animation loop, remove the canvas from the DOM, and clear texture references.

// Stop the render loop
Matter.Render.stop(render);

// Remove the canvas element from the DOM
if (render.canvas) {
    render.canvas.remove();
}

// Clear internal reference arrays
render.canvas = null;
render.context = null;
render.textures = {};

3. Clear the World and Engine

Clearing the composite removes all bodies, constraints, and composite children from the simulation space, while clearing the engine resets its internal caches.

// Clear all bodies, constraints, and composites from the world
Matter.Composite.clear(engine.world, false);

// Clear the engine instance
Matter.Engine.clear(engine);

Note: Passing false as the second argument to Composite.clear() ensures that the root composite itself is kept clean without throwing errors, while deep-clearing all child components.

4. Unbind Event Listeners

If you have attached custom events to the engine, runner, or render instances, deregister them to allow proper garbage collection.

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

5. Nullify Object References

Finally, set all primary instance variables to null so the JavaScript garbage collector can release the memory.

engine = null;
runner = null;
render = null;

Complete Teardown Function

Here is a unified cleanup function that consolidates all the steps above into a single, reusable utility:

function destroyMatterInstance({ engine, runner, render }) {
    // 1. Stop the runner
    if (runner) {
        Matter.Runner.stop(runner);
    }

    // 2. Stop and clean up the renderer
    if (render) {
        Matter.Render.stop(render);
        if (render.canvas) {
            render.canvas.remove();
        }
        render.canvas = null;
        render.context = null;
        render.textures = {};
    }

    // 3. Remove event listeners
    if (engine) Matter.Events.off(engine);
    if (runner) Matter.Events.off(runner);
    if (render) Matter.Events.off(render);

    // 4. Clear the physics world and engine
    if (engine) {
        Matter.Composite.clear(engine.world, false);
        Matter.Engine.clear(engine);
    }
}