matter-js-reanimated
v0.1.4
Published
[](https://www.npmjs.com/package/matter-js-reanimated) [](https://www.npmjs.com/package/matter-js-reanimated) [![License:
Readme
🎮 matter-js-reanimated
A UI-thread-safe, functional port of Matter.js, purpose-built to run inside Reanimated 3 worklets on React Native.
This is not a renderer.
This is not for the browser.
This is Matter.js, re-imagined for headless, high-performance React Native physics.
🚀 Why This Exists
matter-js-reanimated is a fork of Matter.js rewritten for the UI thread in React Native using Reanimated 3’s JS runtime and shared memory model. It enables deterministic, frame-synchronous 2D physics simulations directly inside worklets — perfect for Skia, SVG, or declarative game engines.
🧠 Key Differences from Matter.js
- 🔄 All classes rewritten as pure functions
- 🎭 Runs inside
runOnUIworklets - 🧱 No rendering, no DOM, no Canvas
- 📦 Headless and side-effect-free
- ⏱ Manually driven via
useFrameCallback - 🌐 Injected via
global.MatterReanimatedfor worklet access - 📉 Based on Matter.js core but stripped of deprecated or browser-specific APIs
🧪 Example Usage
// 1. Inject Matter modules on the UI thread (run this ONCE before anything else)
runOnUI(() => {
initMatter(); // defines global.MatterReanimated
})();
// 2. Ensure global.MatterReanimated is initialized before using it
// This must be called AFTER the above runOnUI has completed
runOnUI(() => {
'worklet';
if (!global.MatterReanimated) {
console.warn('Matter not initialized yet!');
return;
}
const engine = global.MatterReanimated.Engine.create();
const ball = global.MatterReanimated.Bodies.circle(100, 100, 20);
global.physicsEngine = engine;
global.ball = ball;
global.MatterReanimated.World.add(engine.world, [ball]);
})();// 3. Advance physics manually each frame (typically from a frame callback)
useFrameCallback((frame) => {
runOnUI(() => {
'worklet';
global.MatterReanimated.Engine.update(
global.physicsEngine,
frame.delta
);
})();
});// 4. Access body position from any UI-thread worklet (e.g., derived value, Skia draw, etc.)
const position = useDerivedValue(() => {
'worklet';
return {
x: global.ball.position.x,
y: global.ball.position.y,
};
});💡 You can also read
global.ball.positionfrom any other worklet (Skia drawing loop, touch gesture, animation, etc). It’s just shared memory.
✅ What's Implemented
- [x]
Engine,World,Body,Composite,Vector,Bounds,Sleeping, etc. - [x] Gravity, collision resolution, compound bodies, sleeping
- [x] Worklet-safe structure using
global.MatterReanimated - [x] Hermes-compatible
- [x] Functional, CommonJS-style output
🚫 What’s Not Included (Yet)
- ❌ Rendering (Canvas, DOM, WebGL, etc.)
- ❌ MatterTools, Events, or mouse support
- ❌ Lifecycle helpers or automatic tick systems
- ❌ Plugin system
- ❌ ESM build or tree-shaking support
- ❌ Declarative React components (
<PhysicsWorld />,<RigidBody />)
✅ For rendering, Demo view, Touch Support Example, matter-tools-reanimated is published on NPM!
🧩 Planned Features
- 🧠 Declarative
<RigidBody />,<PhysicsWorld />bindings - ⚙️ Skia or SVG bindings via
useBodyTransform() - ⛓ Constraint hooks like
useDistanceConstraint() - 🔁 Deterministic stepping and time scaling
- 🔌 Worklet-safe plugin registration
🛠 Installation
npm i matter-js-reanimatedTypeScript Setup
For TypeScript projects, include an ambient declaration file (e.g. matter-js-reanimated-env.d.ts) with:
/// <reference types="matter-js-reanimated" />This enables global typings such as MatterReanimated within your worklets.
📦 Build Info
- Output: CommonJS
.jsfile (via Matter.js UMD Webpack config) - Works on: React Native + Hermes + Reanimated 3
- No bundler-specific config yet (e.g., Metro plugin)
📖 Based On
- Original Matter.js by Liam Brummitt
- Reanimated 3 worklet runtime
- Custom internal game engine (WIP)
📄 License
MIT (Same as original Matter.js)
