# IKPy: inverse kinematics in pure Python, with a JAX backend when you outgrow it

> IKPy is a universal inverse kinematics library that reads a robot's kinematic chain from a URDF or a MuJoCo MJCF file and solves for joint positions in position, orientation or both, without requiring a robot, a simulator or a C compiler. Version 4 added an experimental JAX backend that swaps the numerical Jacobian for an analytical one, and the project remains pure Python.

**Phylliade/ikpy** — IKPy, an Universal Inverse Kinematics library

- Repository: https://github.com/Phylliade/ikpy
- Website: http://phylliade.github.io/ikpy
- Stars: 1,038 · Forks: 179
- Language: Python
- License: Apache-2.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/phylliade-ikpy

## A chain description plus an optimiser, and nothing else

The feature list is the clearest statement of what IKPy is, and it is worth taking item by item because each one is a decision about scope.

You can compute the inverse kinematics of every existing robot, in position, orientation, or both. You can define your kinematic chain using arbitrary representations, with DH (Denavit-Hartenberg), URDF, custom and more to come. You can automatically import a chain from a URDF file or a MuJoCo MJCF file. You can support arbitrary joint types, with revolute, prismatic and more to come in the future. And you can use pre-configured robots, such as baxter or the poppy-torso.

There are also utilities to parse and analyze URDF files, and the ability to plot your kinematic chain, which the README frames as no need to use a real robot (or a simulator) to test your algorithms. That last one is arguably the most valuable capability for most users, because the hard part of robotics work is usually getting the maths right before you have hardware.

Two claims about quality are made. IKPy is precise, up to 7 digits, with the only limitation being your underlying model's precision, and fast, from 7 ms to 50 ms depending on your precision, for a complete IK computation. The range is wide because precision is a parameter, and the honest framing is that the answer is as good as the chain description you gave it.

The last feature is the one that makes it a library rather than a script: you can define your own inverse kinematics methods. The developer API exists for adding custom methods and custom robot representations such as DH parameters, which is what makes the library extensible to hardware it has never seen.

## The JAX backend, and what the speedup table does not say

Version 4 brings an optional JAX backend for accelerated inverse kinematics using automatic differentiation, and the README is careful about how it frames the gains.

The table gives a speedup against NumPy: 1.5 to 4 times faster for a single target on complex chains, 2 to 3 times faster for trajectory tracking with warm start, and cold start described as more robust with fewer local minima. The mechanism is an analytical Jacobian computed via autodiff, which gives faster convergence on difficult targets, better robustness against local minima, and significant speedup on robots with 5+ joints.

The claim about local minima is the one that matters most for a robotics user, and it is a structural claim rather than a benchmark claim. The NumPy path relies on finite differences to estimate the Jacobian, which is both slower and noisier, and a noisy gradient is a gradient that can point an optimiser at a local minimum. An analytical Jacobian removes that noise.

The installation is an extra.

```bash
pip install 'ikpy[jax]'
```

And the usage is a keyword argument on the same call.

```python
from ikpy.chain import Chain

chain = Chain.from_urdf_file("my_robot.urdf")

result = chain.inverse_kinematics(
    target_position=[0.5, 0.2, 0.3],
    backend="jax"
)
```

Two caveats are stated. The first JAX call includes JIT compilation overhead, about 1 to 5 seconds, and subsequent calls are fast. And the backend choice table recommends NumPy for simple chains of four joints or fewer with easy targets, JAX for complex chains of five or more, for trajectory tracking, and for real-time control after warmup, while NumPy stays the choice for one-off calculations because of no compilation overhead.

The word experimental in the section heading is the honest summary. The API will move.

## optimizer_budget and tol bound the work, whatever the backend

The configuration section is short and it is the part a user will actually tune.

Two arguments bound the work of the optimiser, and they mean the same thing whichever backend and whichever optimiser you use: optimizer_budget, an approximate number of evaluations allowed, and tol, the convergence tolerance.

```python
chain.inverse_kinematics(
    target_position=target,
    optimizer_budget=10,
    tol=1e-4,
)
```

The budget is a budget rather than a hard cap, because an optimizer finishing a gradient estimation can overshoot it slightly. The README's advice is to use it to trade accuracy for speed in real-time loops. That is a useful framing, because the default behaviour of a least-squares solver is to keep iterating until it converges, and in a control loop you would rather have an answer now than a better answer later.

Everything else goes through optimizer_kwargs, forwarded as-is to the SciPy optimiser in use, which is scipy.optimize.least_squares by default and scipy.optimize.minimize when optimizer is set to scalar.

```python
chain.inverse_kinematics(target_position=target, optimizer_kwargs={"loss": "soft_l1"})
```

The bounds are derived from the limits of the links, so they cannot be set there, and neither can an option that optimizer_budget or tol is already setting. That last restriction is worth internalising, because passing a conflicting option is an error rather than a silent override, which is the right behaviour for a library that has to produce a result you will actuate a robot with.

The JAX backend adds a few options of its own on top, including scipy_method with the values trf, dogbox and lm, scipy_x_scale set to jac for auto-scaling, and use_analytical_jacobian, which can be set to False to fall back to finite differences.

## MuJoCo MJCF import, and the parser behind it

The MJCF support is a separate section in the README and it is a meaningful addition, because MJCF is a different description format with different conventions.

```python
from ikpy.chain import Chain

chain = Chain.from_mjcf_file("ur5e.xml", base_elements=["base"])
```

The parser supports MuJoCo compiler settings and default classes, including childclass inheritance, and there are helpers to inspect models, with ikpy.mjcf.get_body_names and ikpy.mjcf.get_joint_names.

The childclass point is the substantive one. MuJoCo allows a class to define a set of attributes that other elements inherit, and a parser that does not resolve that inheritance will produce a chain with wrong joint limits or wrong geometry. Supporting it is what makes an MJCF import usable with a real robot description rather than only with a hand-written toy file.

The base_elements argument in the example is the other thing to notice. An MJCF file describes a whole scene, and the base_elements parameter selects which element the chain starts from, so a file containing a robot on a table does not turn into a chain that includes the table.

The repository layout supports the picture of a mature library. There is a src/ directory with the package, tests/, tutorials/ with notebooks including the orientation tutorial and the Baxter kinematics tutorial, doc/, contrib/, resources/, scripts/, a ci/ directory, and a CITATION.cff file alongside a Zenodo DOI badge. The README itself is generated from a README.md, and SUMMARY.md at the root is a table of contents, which is a gitbook convention.

## Pure Python, and the cost of that choice

IKPy is a pure-Python library, and the README makes the trade explicitly: the install is a matter of seconds, and no compiling is required.

That matters more than it sounds. The alternative for a Python robotics developer is a compiled extension or a JIT-compiled numerical stack, either of which means a build step, a compiler toolchain and platform-specific wheels before you can solve your first inverse kinematics problem. A library that installs with pip install ikpy and runs on the interpreter you already have removes a whole category of first-day friction.

The dependencies are correspondingly modest. It requires numpy and scipy. sympy is highly recommended for fast hybrid computations, which is why it is installed by default. matplotlib is optional and is used to plot your models in 3D.

The optional extras map onto the optional features.

```bash
pip install ikpy
pip install 'ikpy[plot]'
pip install 'ikpy[jax]'
```

From source, the instructions are to download and extract the archive and run pip install ./, with a note that you must have the proper rights to execute this command.

The compatibility story is spelled out in the README. Starting with IKPy v4, Python 3.10 or above is required. Starting with v3.1, only Python 3 is supported. For versions before v3.1, the library can work with both versions of Python, 2.7 and 3.x. The last of those lines explains why the v4 major bump exists, since a move to Python 3.10 as a floor is exactly what would justify it.

## Version 4.0 changed the internals, 4.1.0 is the current release

The release history shows v4.1.0 from 2026-08-30, v4.0.0 from 2026-07-05 and v3.4.2 from 2024-08-12, and the last push was on 2026-08-30, so the tree matches the newest tag.

The gap between 3.4.2 in August 2024 and 4.0.0 in July 2026 is a long one, and it is consistent with a major rewrite rather than a feature release. The 4.0 major brought the Python 3.10 floor, the JAX backend, and the MJCF support described above.

Two released artefacts in the tree are worth knowing about. The DOI badge points at 10.5281/zenodo.6551105, and there is a CITATION.cff file, so the project is set up to be cited in a paper, which for a library that appears in academic robotics work is a real consideration rather than a nicety.

The documentation is split across three places, and the split is worth noting when you go looking for something. The wiki is introduced as the place that should introduce you to the basic concepts of IKPy, and the API documentation is an extensive document hosted at ikpy.readthedocs.io. The tutorials directory in the repository holds the worked notebooks, including the Quickstart notebook that the README points you at first, the orientation tutorial, and the Baxter kinematics tutorial.

The homepage is phylliade.github.io/ikpy, and the licence is Apache-2.0 with the LICENSE file at the root. The project is designed to be easily customisable, with a developer API for adding your own IK methods or robot representations such as DH parameters, and the contributing guidance is in the wiki.

## Conclusion

IKPy suits a robotics developer who needs to solve inverse kinematics for a chain described in URDF or MJCF, in Python, without a simulator in the loop, and who wants to plug in their own optimiser or robot representation through the developer API. It is the wrong tool if you need real-time control on a long chain, since the NumPy path takes up to 50 ms per solve and the JAX path pays a one to five second JIT compilation on the first call, and it is the wrong choice if you need closed-loop control with feedback, since the library solves a static problem and does not command a robot. Before you adopt it, read the orientation tutorial, because solving for orientation as well as position is a different problem with different convergence behaviour, and test the optimiser_budget setting against your precision needs rather than assuming the defaults are appropriate for a control loop.

## FAQ

### What is IKPy and what can it compute?

IKPy is a universal inverse kinematics library in pure Python. It computes the joint positions for a kinematic chain in position, orientation or both, and the chain can be defined in DH parameters, imported from a URDF file, imported from a MuJoCo MJCF file, or defined by your own representation.

### How do I install IKPy with the JAX backend?

Run pip install 'ikpy[jax]'. The JAX backend is optional and selected per call with the backend="jax" argument on inverse_kinematics, and the first call pays a JIT compilation overhead of roughly 1 to 5 seconds.

### What do optimizer_budget and tol control in IKPy?

They bound the work of the optimiser and mean the same thing whichever backend and optimiser you use. optimizer_budget is an approximate number of evaluations allowed, and it is a budget rather than a hard cap because an optimiser finishing a gradient estimation can overshoot it slightly.

### Can IKPy import a robot from a MuJoCo MJCF file?

Yes, with Chain.from_mjcf_file, for example Chain.from_mjcf_file("ur5e.xml", base_elements=["base"]). The parser supports MuJoCo compiler settings and default classes including childclass inheritance, and there are helpers such as ikpy.mjcf.get_body_names and ikpy.mjcf.get_joint_names.

### What are IKPy's dependencies and Python requirements?

It requires numpy and scipy, with sympy highly recommended for fast hybrid computations and installed by default, and matplotlib optional for 3D plotting. Starting with v4, Python 3.10 or above is required.

## Sources

- [License: Apache-2.0](https://github.com/Phylliade/ikpy/blob/master/LICENSE)
- [Phylliade/ikpy on GitHub](https://github.com/Phylliade/ikpy)
- [Project website](http://phylliade.github.io/ikpy)
- [README](https://github.com/Phylliade/ikpy/blob/master/README.md)
- [Releases](https://github.com/Phylliade/ikpy/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/phylliade-ikpy
