The Problem

Developers need a lightweight, deterministic way to step through animated explanations of code changes. Existing visualizers rely on heavy frameworks or runtime dependencies, making them hard to embed in browsers, Cloudflare Workers, or Node scripts. Lantern offers a zero‑dependency TypeScript core that renders SVG frames and records state at each step, enabling reproducible, inspectable explanations.

What This Does

Lantern implements a small animation engine inspired by manim. A scene is a class in scenes/*.ts that extends Scene from src/scene.ts. Inside construct() the scene emits steps with this.step('label'), and animation primitives such as FadeIn, Create, and Arrow live in src/animation.ts. The core model tracks geometry in Mobject and VMobject trees (src/mobject.ts, src/vmobject.ts), serialises to SVG via src/svg.ts, and exposes a StringSink that returns a <svg> string. The engine also records a trace of the scene’s state at each step (src/trace.ts).

npm run dev launches a Vite dev server that serves app/index.html, which pulls in app/main.ts. This bootstrap file imports the scene registry (scenes/index.ts) and the library (src/index.ts) to render the requested scene. Tooling scripts in tools/*.ts provide CLI helpers such as see, shot, and verify:motion, making it easy to view a frame, generate a contact sheet, or run motion‑verifier tests.

How It Is Wired

Execution starts at app/main.ts. It reads the query string (scene and step), resolves the scene class from scenes/index.ts, and creates an instance. The instance calls construct(), which internally uses this.play() to enqueue animations. Each animation is a pure function of time; when the engine steps forward, src/scene.ts invokes Animation.begin() and Animation.end(), then the StringSink writes the updated geometry to src/svg.ts.

The trace is collected by src/trace.ts at every this.step() boundary, producing a JSON document that records this.state. The same trace is consumed by tools/verify.ts during npm run verify, ensuring that the frame output is stable across seeks. The library has no external runtime dependencies; all geometry is contained in typed arrays (Float32Array), and font glyphs are embedded in vendor/glyph.js.

src/index.ts re‑exports the public API (Scene, Mobject, Arrow, etc.) so that consumers import from the library root. The CI pipeline (.github/workflows/ci.yml) runs npm test, executing the 18 test files under test/. Each test imports from src/index.ts and validates rendering, tracing, and state transitions.

The tool chain (tools/*.ts) is separate from the runtime; for example, tools/render.ts reads a scene file and writes SVG to disk, while tools/shot.ts captures PNG snapshots of each step. These scripts use the same core modules, ensuring that the CLI outputs match what would appear in the browser.

How To Use It

Setup

git clone https://github.com/moses-y/lantern
cd lantern
npm install

Configuration

No external config files are required. The project ships a wrangler.toml for Cloudflare Workers, but the local dev server runs on Vite (node_modules/.bin/vite).

Running It

npm run dev                # http://localhost:5173/?scene=pyex-limits
npm run see pyex-limits after   # prints SVG + state diff
npm run shot pyex-limits   # PNG contact sheet
npm test                  # unit tests; `npm run test:full` for all frames

All commands reference existing script files in tools/*.ts and entry points in app/.

Real‑World Use

A team can embed Lantern in a CI pipeline to generate animated documentation for pull‑request diffs. The tools/see script can be invoked in a GitHub Action to output an SVG that is attached to a PR comment. Because Lantern produces deterministic traces, the same animation can be rendered on the client and on a serverless worker, ensuring consistency across browsers.

Code Health & Issues

  • Tests: 18 files under test/; npm test runs in ~8 s.
  • CI: One workflow (.github/workflows/ci.yml) that runs tests, type‑checks, and builds the dist/ folder.
  • License: MIT license in LICENSE.
  • Missing: No Dockerfile or container build script; CI uses Vite locally. No coverage reporting is configured.

No runtime dependencies are declared in package.json, confirming the zero‑dependency claim. The code compiles with TypeScript 5.4, and tsc emits a complete dist/ directory.

The Bottom Line

Lantern delivers a compact, deterministic animation engine that can be executed in the browser, on Cloudflare Workers, or in Node, with no runtime dependencies. Its TypeScript core and SVG output make it suitable for generating reproducible, step‑by‑step explanations of code changes. The project is well‑tested and CI‑backed, though it lacks containerization and coverage metrics. Engineers needing lightweight, reproducible visualizers for code or algorithm explanations should consider Lantern.