v0.21.0

Date

August 10, 2026

What’s Changed

Breaking Changes 🚨

  • Delegate color handling in Code to Pygments and document custom styles by @Helbronner in PR #4816

    Code no longer honors foreground color overrides passed through paragraph_config={"color": ...} or Code.default_paragraph_config["color"]; syntax and line-number colors now come from the selected Pygments formatter_style. To customize them, pass a custom Pygments Style subclass through formatter_style and configure its token styles and line_number_color. Background colors can still be overridden with background_config={"fill_color": ...}; otherwise, the selected Pygments style provides the background. See the note in the documentation of Code for an explicit example.

  • Speed up Cairo renderer by 2.2x on animation-heavy scenes by @HamdiBarkous in PR #4695

    Cairo path construction now uses vectorized subpath splitting, and pixel-array handling avoids redundant copies while producing pixel-identical output. This changes Camera.convert_pixel_array(): the convert_from_floats argument has been removed, and the method now always converts floats to the camera’s pixel format. Omit the argument if it was previously True; use np.array(pixel_array) instead if relying on the old default copying behavior.

Highlights 🌟

  • Introduce first-class support for rendering text and markup via Typst (optional dependency) by @behackl in PR #4681

    The new Typst and TypstMath mobjects compile Typst markup and mathematical expressions directly to SVG without requiring a TeX installation. They support label-based subgroup selection, {{ ... }} expression grouping, and integration with existing label APIs. Install the optional dependency with pip install "manim[typst]".

  • Hash NumPy arrays without JSON expansion by @dexhunter in PR #4883

    NumPy arrays in scene cache keys are now represented by deterministic hashes of their complete logical contents instead of sampled JSON data. This prevents stale cache hits when visible image data changes and reduces hashing CPU time by roughly 94–98% in representative benchmarks.

  • Add support for encoding partial movie files in parallel by @pjfo in PR #4899

    The new max_inflight_encoders configuration option allows partial movie encoding to overlap with rendering while bounding the number of encoder workers. Try it with manim render --max-inflight-encoders 4 --encoder-queue-size 8 scene.py Scene; --encoder-queue-size limits the pending frame buffers held by each encoder. The default of one in-flight encoder preserves serial behavior; higher values reduced an encoding-heavy benchmark by 56% and larger real-world renders by roughly 8–11%.

New Features ✨

Enhancements 🚀

Bug Fixes 🐛

Documentation 📚

Testing 🧪

Infrastructure & Build 🔨

Code Quality & Refactoring 🧹

Type Hints 📝

Other Changes

New Contributors

Full Changelog: Compare view