Feeding a clanker? Grab this page as raw `.md` →

# ManimWeb API


 Bases: `AnyWidget`


Run a `manim-web <https://github.com/maloyan/manim-web>`_ scene in a notebook.


`manim-web` is a TypeScript/WebGL reimplementation of Manim that renders animations entirely in the browser. This widget is a thin runner: it loads the manim-web engine from a CDN, then executes a blob of JavaScript you supply (the `code` traitlet). The animation plays inline; Python's only job is to hand over the source and the sizing.


Your JavaScript is run as the body of an async function with the manim-web module namespace (`manim`), the target DOM element (`container`), the `width` / `height` ints, and the widget `model` in scope. The recommended entry point is manim-web's own `Player`, which renders a full playback UI into `container` — play/pause, a scrub timeline with segment markers, speed control, fullscreen and export::


```
const player = new manim.Player(container, {
    width, height, autoPlay: true, backgroundColor: manim.WHITE,
});
player.sequence(async (scene) => {
    const circle = new manim.Circle({
        radius: 1.5, color: manim.BLUE, fillOpacity: 1,
    });
    await scene.play(new manim.Create(circle));
});
```


`PlayerOptions` extends `SceneOptions`, so `width`/`height`/ `backgroundColor` work alongside `autoPlay` and `loop`. Colours are plain hex strings (`manim.BLUE`, or `"#e94560"` directly); set `fillOpacity: 1` for solid shapes on a light background.


The code is executed verbatim in the browser, so only pass JavaScript you trust (typically your own).



```
from wigglystuff import ManimWeb

import marimo as mo
from wigglystuff import ManimWeb

scene = '''
    const player = new manim.Player(container, {
        width, height, autoPlay: true, backgroundColor: manim.WHITE,
    });
    player.sequence(async (scene) => {
        const c = new manim.Circle({
            radius: 1.5, color: manim.BLUE, fillOpacity: 1,
        });
        await scene.play(new manim.Create(c));
    });
'''
mo.ui.anywidget(ManimWeb(code=scene, width=800, height=450))
```


Point at a local file or a URL instead of an inline string — the first argument accepts any of the three forms:


```
ManimWeb("scenes/intro.js")
ManimWeb("https://example.com/scene.js")
```


Create a ManimWeb widget.


The scene source is resolved in Python, so the browser always receives plain JavaScript. `code` (or `src`) may be any of:



- an inline JavaScript string,

- a path to a local `.js` file, or

- an `http(s)://` URL.


URLs and file paths are fetched/read here at construction time; the detection is by value, so `ManimWeb("https://.../scene.js")` and `ManimWeb("const s = new manim.Scene(...)")` both do the right thing.




| Type | Description |
| --- | --- |
| `ValueError` | If neither or both of `code` and `src` are given. |

 Source code in `wigglystuff/manim_web.py`

```
def __init__(
    self,
    code: Optional[str] = None,
    *,
    src: Optional[str] = None,
    width: int = 500,
    height: int = 300,
    version: str = "0.3.24",
    **kwargs: Any,
) -> None:
    """Create a ManimWeb widget.

    The scene source is resolved in Python, so the browser always receives
    plain JavaScript. ``code`` (or ``src``) may be any of:

    * an inline JavaScript string,
    * a path to a local ``.js`` file, or
    * an ``http(s)://`` URL.

    URLs and file paths are fetched/read here at construction time; the
    detection is by value, so ``ManimWeb("https://.../scene.js")`` and
    ``ManimWeb("const s = new manim.Scene(...)")`` both do the right thing.

    Args:
        code: Inline JavaScript, a local file path, or an ``http(s)://``
            URL. Mutually exclusive with ``src``.
        src: An explicit alias for ``code`` (same accepted forms), handy
            when the intent is "load from here". Mutually exclusive with
            ``code``.
        width: Container width in pixels.
        height: Container height in pixels.
        version: The manim-web version to load from the CDN.
        **kwargs: Forwarded to ``anywidget.AnyWidget``.

    Raises:
        ValueError: If neither or both of ``code`` and ``src`` are given.
    """
    if (code is None) == (src is None):
        raise ValueError("Provide exactly one of `code` or `src`.")

    source = code if code is not None else src
    super().__init__(
        code=self._resolve_source(source),
        width=width,
        height=height,
        version=version,
        **kwargs,
    )
```


## Synced traitlets


| Traitlet | Type | Notes |
| --- | --- | --- |
| `code` | `str` | Resolved scene JavaScript (inline JS, or the contents of a file / URL, fetched in Python), run against the manim-web `manim` namespace and a `container` element. |
| `width` | `int` | Container width in pixels. |
| `height` | `int` | Container height in pixels. |
| `version` | `str` | manim-web version loaded from the CDN. |
| `error` | `str` | Read-back of the latest JS runtime error, or `""`. |
