Skip to main content

minimal_mjx

Starter code for MJX-based reinforcement learning from the Dynamic Mobility Lab. It is built on MuJoCo Playground and Brax PPO, and keeps training, checkpointing, and evaluating policies simple:

  • Swappable backend. Write an environment once and run it on JAX/MJX (jnp) for fast parallel training, or on NumPy/C MuJoCo (np) for fast, debuggable rollouts.
  • Base environment class (SwappableBase) with common reward terms and helpers.
  • Config-agnostic library. Library functions take plain arguments (run_dir, ppo_params, network_params, ...). mm.utils.Config is the only code that knows the YAML layout, so you can use your own layout by subclassing it or skip it.

Install

pip install minimal_mjx            # from PyPI
pip install -e ".[dev]"            # from source, with pytest

Repository layout

src/minimal_mjx/
  envs/generic/base.py    SwappableBase: backend switching, reward helpers, history buffers
  learning/training.py    train(): runs Brax PPO into a run dir, checkpoints, resumes
  learning/inference.py   load_policy(run_dir), get_last_model(run_dir), get_step_reset()
  eval/rollout.py         rollout_policy(): roll out a policy, record data, render video
  utils/config.py         Config (the only YAML-aware code), read_config(), save_config()
  utils/plotting.py       reward/data plotters, save_video(), save_metrics()
  utils/logging.py        Weights & Biases helpers (init, upload/download checkpoints)
  utils/state.py          EnvState, the NumPy-backend counterpart of mjx_env.State
example/                  a complete Cheetah task (see below)
tests/                    pytest suite

Example: Cheetah

example/ shows the full workflow on DeepMind Control's Cheetah:

File Purpose
cheetah.xml MuJoCo model
cheetah.py Cheetah(SwappableBase): reset, step, observations, rewards, termination
cheetah.yaml Run config: name, save dir, backend, env_config, learning_params
create_environment.py Maps the config's env name to an environment class
simulate.py Rolls out a zero-action policy to check the environment
train.py Trains with PPO (logs to W&B; set USE_WANDB = False to turn this off)
rollout.py Loads the latest checkpoint and renders a rollout
cheetah_model_input.py Lean Cheetah that takes the mjx.Model as an argument, so many model variants can be vmapped (used by scripts/rollout_cheetah_models.py)

Run each script from the repository root and pass the config as its argument:

python -m example.simulate example/cheetah.yaml   # video + reward plot in example/videos, example/plots
python -m example.train    example/cheetah.yaml   # checkpoints in <save_dir>/<name>/
python -m example.rollout  example/cheetah.yaml   # roll out the latest checkpoint

Use backend: np for simulation and rollouts. Training always builds the jnp version. Before training, simulate once with backend: jnp to check that your environment is JAX-compatible.

To roll out an older policy, pass the config.yaml saved in that run's directory. Its git_hash records the commit the run was trained at. Runs named test can be overwritten and skip the git hash; any other name refuses to overwrite an existing run.

Writing your own environment

Subclass mm.envs.SwappableBase and implement reset, step, reward_function, _get_obs, and action_size. To stay backend-agnostic, use the backend handles instead of np/jnp directly: self._np, self._step_fn, self._data_init_fn, self._set_val_fn, self._uniform, and so on. Rewards come back as a dict {name: value}, and get_reward_and_metrics weights them by env_config.reward.weights. Use state.info to carry values from one step to the next.

Using the API directly

import minimal_mjx as mm

cfg = mm.utils.Config('example/cheetah.yaml')   # cfg.env_name, cfg.env_params, cfg.run_dir, ...
env = Cheetah(env_params=cfg.env_params, backend=cfg.backend)

policy = mm.learning.inference.load_policy(cfg.run_dir)
frames, traj, rewards, data, info = mm.eval.rollout_policy(policy, env, n_steps=500)
mm.utils.plotting.save_video(frames, env.dt, 'videos/rollout.mp4')

Training follows the same pattern (see example/train.py):

run_dir = mm.learning.create_training_directory(cfg.run_dir, overwrite=cfg.is_test)
cfg.save(run_dir / 'config.yaml', make_dir=False)      # records the git hash
mm.learning.train(env, env, run_dir, cfg.ppo_params, cfg.network_params,
                  algorithm=cfg.algorithm, overwrite=cfg.is_test)

For a different YAML layout, subclass Config and override its properties (as moplayground's MOConfig does), or pass the arguments yourself.

Tests

pytest            # fast suite (~15 s, CPU)
pytest -m slow    # rendering, video, and a tiny end-to-end PPO run

Metadata

Release files for minimal-mjx 0.1.16

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for minimal-mjx 0.1.16
File Size Uploaded
minimal_mjx-0.1.16.tar.gz 35.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for minimal-mjx 0.1.16
File Interpreter ABI Platform
minimal_mjx-0.1.16-py3-none-any.whl Python 3 none any Details

Total release size: 65.4 kB

Release files / minimal_mjx-0.1.16.tar.gz

Download URL minimal_mjx-0.1.16.tar.gz
Size 35.6 kB
Tags Source
SHA-256 checksum
How to use checksums
ca92fe756f726252cf4e0bb026be71080f0fd190dbc4fadd20dde991daf7201e
BLAKE2b-256 checksum
How to use checksums
461b06fada6718cb5c83c4963589c8f99ac9a6683ca8aff8d9ab105271e3c215
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / minimal_mjx-0.1.16-py3-none-any.whl

Download URL minimal_mjx-0.1.16-py3-none-any.whl
Size 29.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bd87bbc6f1e999889a107a824b1809feec1541c4bda5195fe4ddfc5498f07ffe
BLAKE2b-256 checksum
How to use checksums
df8a44b0d95c70faaf6f1f9a0b7628278c92c659715e12f14aeff6a2238df604
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.19

2 release files

0.1.18

2 release files

0.1.17

2 release files

This release

0.1.16 This release

2 release files

0.1.15

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page