Most DSA visualisers animate their implementation of a textbook algorithm. VisionDS animates yours. You paste in the solution you actually wrote, hit run, and watch a smooth animated dry-run of your own execution, then jump straight to the exact step where the output stops matching the expected one. It is built for students grinding LeetCode-style problems, where the hard part is rarely the concept and almost always finding the line where your mental model and the machine stopped agreeing.
What it does
- Traces the student’s real code rather than a canned reference implementation.
- Renders each step as an animated stage you can scrub through.
- Jumps to the failing step, so debugging becomes a place in a timeline instead of a guess.
- Runs entirely in the visitor’s own browser sandbox. Nothing is uploaded.
The trace format is the contract
The interesting decision is architectural. A trace-schema package defines a
single language-agnostic ExecutionTrace format, with Zod schemas, hard caps
and pointer-role inference. Everything downstream of a runner speaks only that
format.
The consequence is that the visualiser knows nothing about Python. Today the
only runner is a PyodideRunner: a Web Worker boots Pyodide, a WASM build of
CPython served locally, and runs the student’s code under a sys.settrace
tracer that records every step with capped snapshots of the locals. Adding C++
or Java later means implementing one server-side Runner against the same
interface, with no change to the trace format and no change to the UI.
Making a runaway loop boring
Executing arbitrary student code in the browser invites the obvious failure: an infinite loop that freezes the tab. VisionDS bounds it from four directions at once. Ten thousand steps maximum, a five second wall clock, capped snapshot sizes, and a watchdog that terminates the worker outright. A runaway program ends as a clean “trace truncated” verdict rather than a hung page.
AI as decoration, never as truth
An optional “Explain this run” action sends the code and a compact digest of
the trace to Gemini, which returns a failure summary and subtitle-style
captions that follow the scrubber. Two rules keep it honest: the trace stays
ground truth, and any annotation pointing at a step that does not exist is
dropped. The key lives in the visitor’s own localStorage and goes only to
Google. A provider-agnostic Explainer interface means other models can plug
in beside the Gemini one.
Where it is going
A browser extension that captures code and testcases straight from a LeetCode tab is the planned next layer, along with the server-side runners for compiled languages that the trace format was designed to accept.