Create Matter.js Plugins with Matter.Plugin.register
This guide demonstrates how to use
Matter.Plugin.register to build, structure, and distribute
reusable community extensions for the Matter.js 2D physics engine. You
will learn the required plugin schema, how to safely hook into Matter.js
lifecycle methods using internal utilities, and how to activate and
publish your extension for other developers to integrate seamlessly into
their projects.
The Plugin Object Specification
To create a plugin compatible with the Matter.js module system, you
must define an object that conforms to the plugin interface. This object
requires standard metadata properties and an install
method:
name(string): The unique name of your plugin (typically matching your npm package name).version(string): A semantic version string representing the current release.for(string, optional): The name and version range of the target library or dependency (e.g.,'matter-js@^0.19.0').uses(array, optional): An array of other plugin dependencies that must be installed first.install(function): The execution function called when the plugin is activated. It receives the host library reference (usuallyMatter) as its primary argument.
Registering the Plugin
Call Matter.Plugin.register to register your plugin
definition with the global Matter.js plugin registry. This step
validates the plugin object and makes it accessible via
Matter.use().
import Matter from 'matter-js';
const MatterAttractor = {
name: 'matter-attractor',
version: '1.0.0',
for: 'matter-js@^0.19.0',
install(base) {
// Extend or patch Matter.js modules here
base.Body.setAttractor = function(body, attractor) {
body.attractor = attractor;
};
// Hook into the engine update loop
base.after('Engine.update', function() {
// Access the engine instance via 'this'
const engine = this;
const world = engine.world;
const bodies = base.Composite.allBodies(world);
for (let i = 0; i < bodies.length; i++) {
if (bodies[i].attractor) {
bodies[i].attractor(bodies[i]);
}
}
});
}
};
// Register the extension
Matter.Plugin.register(MatterAttractor);
export default MatterAttractor;Hooking into Matter.js Methods
Avoid directly overriding methods on the core namespace to prevent
breaking compatibility with other plugins. Instead, use Matter's
built-in event-chaining hooks: base.before and
base.after.
base.before(targetPath, callback): Executes your callback immediately before the specified function runs.base.after(targetPath, callback): Executes your callback immediately after the specified function completes.
Inside these callbacks, this refers to the instance of
the object executing the function (such as the specific
Engine or Runner), and arguments passed to the
original function are forwarded to your callback.
Consuming the Plugin
Once a plugin is registered, end users can activate it using
Matter.use():
import Matter from 'matter-js';
import MatterAttractor from 'matter-attractor';
// Activate via the plugin object or registered name
Matter.use(MatterAttractor);
// Alternatively: Matter.use('matter-attractor');
// The extension's methods are now available
const engine = Matter.Engine.create();
const body = Matter.Bodies.circle(100, 100, 20);
Matter.Body.setAttractor(body, (b) => {
// Custom attractor logic
});Matter.use resolves dependencies defined in the
uses array, prevents duplicate installations, and checks
version constraints set in the for field.
Packaging for the Community
When preparing your extension for distribution via npm:
- Set the
peerDependenciesin yourpackage.jsonto includematter-js. - Register the plugin automatically when the script is imported, but also export the plugin object as the default export.
- Support both CommonJS and ES module environments using standard bundlers (like Rollup or Vite) to ensure compatibility across Node.js and browser-based build pipelines.