← back to all projects

VisionDS: a DSA visualiser that traces your own code

0 servers student code never leaves the browser

React · TypeScript · Vite · Zod · Pyodide (WASM) · Web Workers · pnpm monorepo

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

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.