Mantis.js is a JavaScript library for the kinematics and motion control of six-legged robots. It combines analytic inverse kinematics, quaternion-based body orientation, world-space foot anchoring and phase-based gait generation in a compact model that can be used both for simulation and for driving a real hexapod.
The mathematical model is independent of p5.js. Rendering is optional and uses the same state that is available to headless applications.
The included p5.js example is useful for tuning dimensions, stance, gait timing and controller behavior before transferring the resulting joint angles to hardware.
npm install
npm run build
npm run devOpen http://localhost:8000/examples/default.html.
The visualization can be controlled with the arrow keys or a gamepad. A second example at examples/gaits.html shows the timing and lift profile of each leg independently.
Mantis.js uses a robotics-style right-handed coordinate system:
X = forward
Y = left
Z = up
The p5.js renderer performs the graphics-space conversion internally, leaving the kinematic model in robot coordinates.
Each leg is modeled as a three degree-of-freedom chain:
coxa -> femur -> tibia
legIK() accepts a target in the local coordinate frame of a leg and returns the three joint angles together with reachability information. For a complete robot, Mantis.js transforms world-space foot targets into body space and then into the corresponding leg frame before solving the same analytic IK for all six legs.
neutralReach is the horizontal neutral foot offset measured outward from the end of the coxa. It is a stance parameter, not the maximum geometric reach. The reachable workspace itself follows from the femur and tibia lengths. For a vertical distance h between the coxa plane and the ground, the maximum horizontal reach beyond the coxa is
sqrt((femur + tibia)^2 - h^2)
provided that the leg can fully extend to that height. A neutral stance should remain comfortably inside the workspace so that each leg retains room for gait motion in every direction.
Mantis.js includes four phase-based gait presets:
- Tripod
- Tetrapod
- Ripple
- Wave
A duty factor divides each leg cycle into stance and swing. During stance, the foot remains anchored to the ground in world space. During swing, the foot advances to its next landing point along a smooth trajectory. Gait changes and transitions back to a neutral stance are blended rather than applied as discontinuous target jumps.
Install from npm:
npm install @rawify/mantisThe primary package entry is a modern ES module. quaternion and @rawify/vector3 remain normal external dependencies and are not bundled into Mantis.js.
import Mantis, { WebGamepad, legIK } from "@rawify/mantis";
const mantis = new Mantis({
leg: {
coxa: 30,
femur: 100,
tibia: 150,
neutralReach: 125,
},
});
mantis.setBodyPose({
height: 110,
roll: 0,
pitch: 0,
yaw: 0,
});
mantis.update(0, {
gait: "tripod",
speed: 1,
stride: 72,
lift: 42,
duty: 0.62,
treadmill: true,
dt: 1 / 60,
drive: { forward: 1, turn: 0 },
});
const angles = mantis.getServoAngles();getServoAngles() returns 18 logical joint angles in radians: coxa, femur and tibia for each of the six legs.
A transpiled ES5 browser build is available as dist/mantis.min.js. It is generated from the same modern source as the ESM build, wrapped in an IIFE, and deliberately does not bundle Quaternion.js or Vector3.js. Load those libraries first so that the global identifiers Quaternion and Vector3 are available:
<script src="path/to/quaternion.min.js"></script>
<script src="path/to/vector3.min.js"></script>
<script src="path/to/mantis.min.js"></script>
<script>
var mantis = new Mantis();
</script>The browser build exposes the same convenience API on Mantis, including Mantis.Gamepad, Mantis.Gaits, Mantis.legIK() and Mantis.legJoints().
The body pose can be specified through position plus roll, pitch and yaw, or by passing a Quaternion directly:
mantis.setBodyPose({
position: [0, 0, 110],
orientation: quaternion,
});Internally, body-to-world and world-to-body transformations are quaternion rotations. No rotation matrix is required by the model.
WebGamepad is a small adapter around the browser Gamepad API. The left stick produces normalized forward/turn commands and the right stick produces normalized roll/pitch commands:
const gamepad = new WebGamepad({ deadzone: 0.12 });
const input = gamepad.read();The adapter is optional; headless users can provide their own drive and body-orientation commands directly.
npm install
npm run build
npm test
npm run devnpm run dev starts the local example server on port 8000. npm run verify runs tests, builds both distribution targets, validates the browser build and performs an npm package dry run.
Copyright (c) 2026 Robert Eisele
Licensed under the MIT license.
