mrkeyoor.com_
Fri 02 Oct 14:58 UTC
Dev Toolsevaluationupdated 02 Oct 2026

mjbatch review

mjbatch is a Python and C++ library that advances many copies of one MuJoCo model in parallel across CPU threads. It exposes live NumPy views for simulation state and controls, plus per-simulation model fields, so reinforcement learning, control, identification, and design searches can share one compact batch API.

Verdict

Our mjbatch run installed 44 packages in 117 seconds, built in 6 seconds, and passed all 43 tests, making v0.1.2 a credible small library for CPU-batched MuJoCo work. Use it when one model topology, live NumPy arrays, and per-copy parameters describe your workload. Wait if you need Windows, several MuJoCo releases, GPU execution, or batched query operations outside its narrow API.

We ran it

Lab card: what happened when we ran mjbatchScreenshot of mjbatch (github.com/kevinzakka/mjbatch)
Install✓ · 117s44 packages · 169 MB
Build✓ · 6s
Tests✓ · 8s43 passed · 0 failed of 43 (pytest)
Known vulns0(pip-audit)
Repo51 files~3,827 lines of source · 19.4 MB · 1 CI workflows · tests dir

Answers from our run

Does mjbatch build from source?

Dependencies installed in 117 seconds (44 packages), and the build succeeded in 6 seconds. We cloned commit 713f5cf into a clean Debian container with 3 CPUs and no project-specific setup.

Do mjbatch's tests pass?

Yes: 43 of 43 passed when we ran the project's own test command (pytest). Some failures need services or credentials a bare container does not have.

Does mjbatch have known vulnerabilities in its dependencies?

pip-audit found none in the dependency tree at the time of our run.

Who should not use mjbatch?

GPU-first simulation stacks: mjbatch uses a C++ CPU thread pool and makes no GPU execution claim.

What are the alternatives to mjbatch?

MuJoCo, Brax, Isaac Lab. Our mjbatch run installed 44 packages in 117 seconds, built in 6 seconds, and passed all 43 tests, making v0.

Setup4/543 tests pass, but native setup took 117 seconds
Docs4/5Compact API explanation with seven runnable examples
Community3/5581 stars and five open issues or PRs after three weeks
Maturity3/5v0.1.2 is tested and released, but the API is very young

Who it’s for

Robotics researchers running many independent copies of the same MuJoCo model on CPU.
Teams that want live NumPy access to batched state and control arrays without a Python loop around every simulation.
Control, system-identification, and hardware-design experiments that vary model parameters per simulation.
Python users comfortable with a compiled extension and an exact MuJoCo version pin.

Who it’s NOT for

GPU-first simulation stacks: mjbatch uses a C++ CPU thread pool and makes no GPU execution claim.
Windows or musl Linux deployment: the wheel configuration skips Windows, musllinux, and 32-bit builds.
Projects that must stay on MuJoCo 3.10 through 3.12: v0.1.2 pins 3.13.0, while multi-version wheel support remains an open pull request.
Users who need native batched jac_site or heightfield sampling today: open issue 2 requests both operations.
Teams demanding a settled long-term API: the repository began in September 2026 and v0.1.2 fixed dropped field writes.

Setup reality

Our sandbox installed commit 713f5cf in 117 seconds, adding 44 packages and using 169 MB. The build passed in 6 seconds. All 43 pytest tests passed in 8 seconds, and pip-audit found 0 known vulnerabilities.

No credentials or hosted services are required. Building needs Python 3.10 or newer, MuJoCo 3.13.0, NumPy, scikit-build-core, nanobind, and CMake 4.1 or newer. The project publishes wheels for selected Linux and macOS targets.

The repository has CI and a tests directory but no Dockerfile. Several examples need an optional dependency group, and examples that open a viewer require a display; a headless flag runs their solver without a window.

One model can drive thousands of CPU simulations

mjbatch takes one MjModel, copies it into a batch, and steps those simulations through a C++ thread pool. The Python GIL is released during native work. A caller sees arrays whose first dimension is the simulation count, so policy code can read positions, write controls, and advance the whole batch without a Python loop for each environment. The README's example creates 4,096 copies, though our lab did not measure simulation throughput or scaling.

The useful detail is that these are live views. bind("qpos") and bind("ctrl") expose simulation data as NumPy arrays, while named accessors cover joints, actuators, bodies, sites, and sensors. expand turns a model field such as geometry friction into per-simulation data, and set_const recomputes derived constants after edits. That is a good fit for parameter sweeps, randomized training, system identification, and hardware co-design using one shared topology.

The four core operations keep the API small

The public idea is mostly bind, expand, step, and reset. Version 0.1.2 also pins NumPy plus MuJoCo 3.13.0 rather than building a framework around environments, rewards, policies, or distributed workers. Researchers retain ordinary MuJoCo models and write the surrounding algorithm themselves. Seven examples cover cart-pole control, locomotion, a humanoid flip, throwing-arm design, and inertial identification. Some add PyTorch and model assets through an optional examples group.

A small API also means omissions surface quickly. Issue 2 asks for batched site Jacobians and heightfield sampling because a robot-learning framework needs those calls on its hot path. Neither operation appears in v0.1.2. The batch starts from one template model, so the natural unit is many parameterized copies rather than unrelated robot structures. Check every MuJoCo query your controller uses before replacing an existing vectorized backend.

What happened when we ran it

Our sandbox installed commit 713f5cf in 117 seconds, pulling 44 packages and occupying 169 MB. The native build finished in 6 seconds. Pytest then passed all 43 tests in 8 seconds, with 0 failures, and pip-audit reported 0 known vulnerabilities. The fresh Debian container had 3 CPUs, 8 GB of RAM, Python 3.12, no secrets, and no elevated privileges. The repository also supplied one CI workflow and a tests directory.

Those results cover compilation and correctness checks, not the performance claims in the README. We did not time simulation steps, compare thread counts, train a controller, or open the graphical examples. The 19.4 MB checkout also contains several GIFs and model assets, so repository size does not describe runtime memory. What we can say is narrower and useful: installation completed, the extension built, and every one of the 43 supplied tests passed on our CPU-only box.

MuJoCo 3.13.0 is an exact dependency

The v0.1.2 project configuration requires Python 3.10 or newer and pins MuJoCo exactly to 3.13.0 for both building and runtime. CMake 4.1 or newer and nanobind build the extension. Published-wheel automation targets CPython 3.10 through 3.14, including free-threaded 3.14, across glibc Linux and macOS runners. Windows, musllinux, and 32-bit targets are skipped.

That exact pin is the largest integration question for an existing robotics stack. Open pull request 6 proposes separate wheels for MuJoCo 3.10 through 3.13, but it is not part of the current release. A project with plugins or environments pinned to another MuJoCo version must either move them together or wait. Docker is not provided, so teams that want a frozen compiler and library environment must write and maintain their own image.

The 0.1.2 release fixed a state-write bug

Release v0.1.2 shipped September 30, 2026. It fixed writes being discarded after a bind("state") row write when reset was called. That is a consequential correctness fix in the library's central promise, and a reminder that this is early software. The repository was created September 10, only 20 days before that release. Pin the exact version and rerun project-level trajectory checks when upgrading.

Maintenance signals are current. GitHub showed 581 stars, two open issues, and three open pull requests on October 2; the API's combined count was five. The last push and latest release both landed September 30. CI tests Ubuntu and macOS on three Python variants, then builds release artifacts with provenance attestations. That is thoughtful release plumbing for a three-week-old project, though time and external adoption still have more to prove.

CPU batching is the reason to choose it

Brax and Isaac Lab make more sense when accelerator execution or a larger robot-learning platform is the requirement. Direct MuJoCo is simpler when you need one environment or broad access to every native query. mjbatch occupies the middle: familiar MuJoCo dynamics, many same-shaped simulations, CPU threads, and NumPy-facing state. Its 43 passing tests make that narrow proposition worth trying.

Start with one representative model and the queries used by your controller. Confirm that bound fields, reset behavior, model expansion, and thread counts reproduce your serial baseline before scaling the batch. If those checks pass, mjbatch removes a lot of Python-side repetition with little conceptual overhead. If you immediately need a missing batched native call, the library's clean core will not compensate for the operation your algorithm cannot express.

Alternatives

ProjectWhat it isPick it when
MuJoCoThe underlying physics engine and Python bindings used by mjbatch.pick this instead when one simulation or direct access to the full MuJoCo API is enough.
BraxA JAX-based physics and learning stack built around accelerator-friendly batching.pick this instead when GPU or TPU execution and JAX transformations matter more than native MuJoCo behavior.
Isaac LabA GPU-oriented robot-learning framework built on NVIDIA Isaac Sim.pick this instead when photorealistic sensors and NVIDIA GPU simulation are part of the job.

What people are saying

  1. [velocity-scout] kevinzakka/mjbatch

Sources

  1. mjbatch README
  2. mjbatch v0.1.2 release
  3. v0.1.2 project configuration
  4. Issue 2: batched query operations
  5. Open multi-version wheel pull request

More dev tools reviews

touchHLE · effect · SwitchHosts · Duo-animation · DuoLikeAnimation · team-Omzo · the whole board →