Browse documentation

How your project becomes Manim Python

The compiler's model: objects, timelines, and clustering.

Your project is a single document: the objects in the scene, the animations on the timeline, the camera, and some settings. There's no hidden state anywhere else — the canvas you're looking at, the timeline, and the render are all just different views onto that one thing. When you press render, the editor turns it into an ordinary Manim scene in Python. Nothing guesses, and no model is involved: the same project always produces exactly the same scene. That predictability is the point of this page — once you know the handful of rules below, you can tell before you render roughly what you're going to get, and if something looks wrong you can open the code view and see why.

One object, built once

Every object in your scene becomes exactly one object in the rendered scene, created once at the start and then animated for the rest of the video. It is never quietly torn down and rebuilt behind your back. Styling — fill, stroke, stroke width — is applied straight after it's created, the same way for every object type, so the result reads like something a person would have written by hand. Each object type in the object reference maps to its natural Manim equivalent.

There's a subtlety worth calling out, because it affects what you see. Objects are created at their resting state — the value a property has before any of its animations have started — rather than at whatever value happens to be showing in the inspector. This matters because of how keyframing works: when you animate a property towards a new value, the inspector field is left holding that destination as a convenience. If the scene were built straight from those fields, the future value would leak backwards into the frames before the animation begins — a circle that's meant to grow at three seconds would already be large at zero. Building from the resting state is what prevents that, and it's the same reasoning the live canvas uses, which is why the frame you see at the very start of the timeline matches the first frame of the render.

How timeline events become a sequence

Manim plays animations one batch at a time, with pauses in between. Your timeline isn't laid out that way — it's a free arrangement of animation bars that can start anywhere and overlap however you like. Turning one into the other follows a simple rule: animations whose time ranges touch or overlap are played together as one batch, and a gap on the timeline between one batch and the next becomes a pause.

This is a useful thing to carry in your head while arranging the timeline. Two animations that merely touch at a single instant, or overlap by a sliver, end up in the same batch — and inside a batch, an animation that starts later than the others gets its own built-in delay so it still begins at the moment you placed it. The result is the timing you drew, but it's worth knowing that nudging one bar so it just barely touches another changes how the two are grouped.

Derivation steps are the one deliberate exception. Because Manim's TransformMatchingTex only does its full bookkeeping — hiding the old line, clearing away intermediate pieces, bringing in the new one — when it's played on its own, derivation steps are always given their own batch rather than being folded in with neighbours. That's why a derivation step never shares a batch with anything else, even if its bar overlaps something on the timeline.

Why animated values are recomputed every frame

A property animation is worked out fresh on every single frame, from its start value, its end value, and how far through the animation you are. That sounds like an implementation footnote, but it has a visible consequence you'd notice if it were done any other way.

The obvious alternative is to work out where a property is heading once, at the moment the animation is set up. That's fine for an animation that plays immediately — but it goes wrong for one that's sitting inside a batch waiting its turn. By the time the delay elapses and the animation actually starts, the object may have moved on from where the plan was made, and the visible symptom is a value that snaps to its start point the instant the delay ends instead of gliding on from where the object already was.

Recomputing every frame avoids that entirely. It's why position, opacity, fill, stroke, stroke width, and most numeric properties animate smoothly no matter where they sit in a busy timeline — a staggered start inside a crowded batch plays exactly as cleanly as an animation on its own.

Why a shape change is a morph, not a tween

Animating a circle's radius, a rectangle's width, or a function graph's tangent position runs into a different problem. Manim shapes aren't defined by a live, adjustable radius or width — the shape's outline is fixed once it's built, so there's no dial to turn gradually the way opacity or colour can be turned.

So a shape change is done a different way: a second copy of the object is prepared with just that one property set to the target value, and Manim's Transform blends between the two shapes. The visible effect is a smooth grow or stretch, exactly what you asked for. Underneath, it's a morph from one shape into another rather than one shape's dimension being turned up.

One practical consequence follows from that. If a shape animation is given an explicit starting size that differs from what's currently on screen, the object has to hop to that starting shape first — near-instantly, a small fraction of a second — before the real animation runs. That hop is what keeps a delayed shape animation smooth instead of jumping, and it's usually invisible. If you ever notice a very brief flick at the start of a size animation, that's what it is, and setting the animation to start from where the object already is removes it.

Why this matters

None of this is hidden from you. Batching, delayed starts, per-frame values, shape morphs — all of it comes out as plain, readable Manim Python that you can open in the code view, copy into a real Manim project, and hand-edit if you outgrow the editor. There's no black box making case-by-case judgement calls at render time: the same project always produces the same scene, and that scene always does the same specific, explainable thing. That's a real trade-off against something "smarter" that might pick a more elegant approach in each individual situation — but it means that when the output looks unusual, there's always a concrete reason you can go and read, not a guess you have to reverse-engineer.

The generated file opens with "Generated by Manim Studio — do not edit by hand. Re-export from the editor instead." That's a suggestion, not a lock: nothing stops you from copying the output into your own script and taking it from there, and the fact that the output is predictable is exactly what makes that a reasonable thing to do.