Export Matter.js World to JSON

Exporting the current state of a Matter.js world to a JSON format is possible, but it cannot be achieved using a standard JSON.stringify() call directly on the engine or world object. Because Matter.js instances contain complex internal structures and circular references between bodies, constraints, and composite hierarchies, direct serialization throws a circular structure error. To export your simulation's state, you must selectively extract and serialize the essential physical properties of your bodies and constraints into a clean data structure.

Why Direct Serialization Fails

A Matter.js World or Engine contains deeply nested references. For example, a Body references its parent body, parts, vertices, and any Constraint attached to it, while constraints simultaneously reference the bodies they connect. Attempting to run JSON.stringify(engine.world) will immediately trigger a TypeError: Converting circular structure to JSON.

How to Export World State

To successfully save the world state to JSON, you need to map over the world's composite elements—specifically bodies and constraints—and extract only the state variables required to represent or restore them.

1. Extracting Body Data

For each body in Composite.allBodies(engine.world), collect properties such as:

2. Extracting Constraint Data

For each constraint in Composite.allConstraints(engine.world), record:

Example Export Implementation

function exportWorldToJson(engine) {
  const bodies = Matter.Composite.allBodies(engine.world).map(body => ({
    id: body.id,
    label: body.label,
    isStatic: body.isStatic,
    position: { x: body.position.x, y: body.position.y },
    velocity: { x: body.velocity.x, y: body.velocity.y },
    angle: body.angle,
    angularVelocity: body.angularVelocity,
    vertices: body.vertices.map(v => ({ x: v.x, y: v.y }))
  }));

  const constraints = Matter.Composite.allConstraints(engine.world).map(constraint => ({
    id: constraint.id,
    label: constraint.label,
    bodyAId: constraint.bodyA ? constraint.bodyA.id : null,
    bodyBId: constraint.bodyB ? constraint.bodyB.id : null,
    pointA: constraint.pointA,
    pointB: constraint.pointB,
    length: constraint.length,
    stiffness: constraint.stiffness
  }));

  const worldState = {
    gravity: {
      x: engine.gravity.x,
      y: engine.gravity.y,
      scale: engine.gravity.scale
    },
    bodies,
    constraints
  };

  return JSON.stringify(worldState, null, 2);
}

Restoring State from JSON

To load the exported JSON back into Matter.js:

  1. Parse the JSON string using JSON.parse().
  2. Clear the active engine world using Composite.clear(engine.world, false).
  3. Recreate the bodies using Bodies.fromVertices() or standard primitives (Bodies.rectangle, Bodies.circle), assigning the stored dynamic properties (velocity, angle, isStatic).
  4. Rebuild constraints by matching the saved bodyAId and bodyBId to the newly instantiated bodies.
  5. Add the restored elements back into the world using Composite.add().