Appearance
Anim at a glance
Anim is a purely functional and statically typed language with a headless renderer for precise 2D animation. You describe a composition in a .anim file, validate it with the CLI, and render an exact frame, image sequence, or video source.
Current status
Anim is an early 0.1 preview. Native CPU rendering, SVG export, the documented language surface, selected Lottie import, FFmpeg-backed video output, and the browser WebAssembly player work today. The language and CLI are not yet stable.
Who it is for
Anim is most useful when animation belongs in a software pipeline:
- product and data-driven motion authored as reviewable source;
- repeatable server-side rendering without a desktop editor;
- exact frame targeting for tests, thumbnails, and distributed work;
- SVG and PNG output generated from the same scene description;
- bounded Lottie conversion where unsupported features must fail clearly.
It is not currently a visual editor, browser UI framework, general 3D engine, or a replacement for the full After Effects feature set.
The core idea
Animated values are functions of presentation time. A tween does not mutate an object on every tick; it describes the value that should exist at any requested time.
text
Signal<T> = exact presentation time → TThat model lets Anim evaluate a targeted frame directly. Time and frame rates use exact rational values, while geometry is sampled on controlled fixed grids for the canonical CPU render path.
anim
let rise = tween(from: 0px, to: -80px, start: 0s, end: 1s);
let fall = tween(from: -80px, to: 0px, start: 0s, end: 1s);
let y = sequence(first: rise, second: fall, at: 1s);
let orb = translate(
x: 160px,
y: 130px + y,
scene: ellipse(
x: -24px,
y: -24px,
width: 48px,
height: 48px,
fill: #38bdf8
)
);
export let main = composition(
width: 320px,
height: 180px,
duration: 2s,
fps: 60fps,
scene: orb
);The workflow
- Write one standalone
.animsource file. - Run
anim checkto catch syntax, type, and unit errors. - Run
anim inspectto confirm dimensions, duration, rate, and frame count. - Render one frame, a half-open range, or an inferred video output.
sh
anim check bounce.anim
anim inspect bounce.anim
anim render bounce.anim --frame 60 -o bounce.svg
anim render bounce.anim --range 0..120 -o frame_%04d.pngEvery executable source exports exactly one main composition. Dimensions, duration, frame rate, and scene content are explicit values rather than ambient project settings.
Current capability boundary
| Available in the preview | Not available yet |
|---|---|
| rectangles, rounded rectangles, ellipses, triangles, cubic paths, and raster images | text shaping, gradients, and general filters |
| stacks, transforms, clips, alpha masks, and group opacity | a production GPU backend |
| tweens, Bézier easing, exact keyframes, sequences, and repeats | an interactive visual editor |
| immutable lists, records, callables, mapping, and collection operations | modules, package resolution, and a public registry |
| exact PNG frames and SVG frame export | audio timelines and built-in AV1/Opus encoding |
| FFmpeg-backed raster or vector video source | a built-in H.264, VP9, or AV1 codec |
| a bounded, fail-closed Lottie importer | broad or silent Lottie compatibility |
| a WebAssembly/Canvas 2D source player | a stable browser runtime API |
The product architecture plan describes longer-term direction. It is not a promise that every planned subsystem exists in the current release.
Determinism, precisely stated
The canonical CPU path controls time conversion, geometry sampling, painter order, linear-light color conversion, alpha compositing, and PNG/SVG serialization. Tests pin exact bytes for supported fixtures.
Video output is different: the CLI can stream raster or vector frames to a locally installed FFmpeg, so the final container and codec bytes depend on that external FFmpeg build and the selected encoder. Use exact image frames when byte-for-byte output is the contract.