Code-oriented Animation eNgine Designed for tYpst
Candy is an animation engine for Typst, using Rust as a high-performance rendering and encoding backend. Inspired by 3Blue1Brown's Manim, with API inspiration from tanim and kino.
Documentation has moved. The full, restructured docs live in
docs/— split into a Tutorial (learn by doing) and a Reference (look things up). This README is a short project overview; the package-specific READMEs aretypst/README.md(user DSL) andrust/README.md(backend API).
- High-performance rendering powered by the Rust
typstcrate — in-process, no CLI invocation. - Code-oriented animation creation, written directly in Typst.
- Video encoding via multiple codecs: the default is
x264(H.264 through systemffmpeg+ libx264, transparently falling back to the self-containedopenh264whenffmpegis unavailable); the pure-Rustrav1e(AV1) andopenh264(H.264) codecs run fully in-process with no external CLI, selectable via--codec av1/--codec h264. - Hand-written MP4 / Matroska / WebM muxers in pure Rust.
- Animated GIF and static PNG output (pure-Rust
gif/png) for quick previews and posters — no codec, no container. - Audio muxing for Opus (
.opus/.ogg→ MKV/WebM) and AAC (.aac→ MP4). - Smooth object transitions (Manim-style
Transform): morph a mobject into new inline content — including formulas — via#transform, keeping the original label reusable. For inline content the transform is glyph-by-glyph;#morph/#fade-transformcrossfade two mobjects. - Progressive text reveal (
#reveal/#typewriter) that types a string mobject in word- or character-by-word while its layout box stays reserved. - Groups & camera:
#groupseveral mobjects to move/scale/rotate them as one, and#camerafor global pan / zoom / rotate "tours";#trackdrives a target through multi-property keyframes. - Familiar appearance for Manim users.
Animations are authored in .tyx files — short for TYpst X-sheet, the Typst
animation exposure sheet. A .tyx file is standard Typst extended with Candy's animation
directives. Instead of manually laying out pages, you declare animatable mobjects and
actions, and Candy's pipeline expands them into per-frame Typst documents that are
rendered and (optionally) encoded.
// dot_move.tyx — valid standard Typst; candy build renders the clip.
#import "@preview/candy:0.1.0": *
#mobject("dot", circle(radius: 1cm, fill: blue))
#animate("dot", to: (4cm, 0pt), duration: 1000, easing: "linear")
#pause(duration: 500)
#audio("voice.opus", blocking: false, loop: false, volume: 0.9, slice: none)The @preview/candy Typst package (the typst/ directory) exposes this DSL. Each directive
is valid, standard Typst: typst compile renders the first frame (no animation); candy build renders the full clip by reading the AST directly.
# From crates.io (published as candy-animation; the binary is `candy`)
cargo install candy-animation
# Or build from source
git clone https://github.com/ViCo-Lab/candy
cd candy/rust && cargo build --releaseSee Tutorial · Install for prerequisites and offline-build notes.
docs/README.md— documentation index.docs/tutorial/— learn-by-doing: install, first clip, animation basics, transforms, scenes/camera/groups, subtitles & counters, output & codecs.docs/reference/— lookup: directives, easing, counters, CLI, codecs, error model, and the Rust API & architecture.typst/README.md— the user-facing Typst DSL reference (also shown on Typst Universe).rust/README.md— the Rust backend developer reference (also on crates.io).
See examples/ for runnable .tyx X-sheets (the
Tutorial · Output and
Typst README worked examples list what each one
demonstrates).
Licensed under either of
- Apache License, Version 2.0 (
LICENSE-APACHEor http://www.apache.org/licenses/LICENSE-2.0) - MIT license (
LICENSE-MITor http://opensource.org/licenses/MIT)
at your option.