Algorithm Visualizer is an interactive platform that turns algorithm code into a live, step-by-step animation. You write (or open) code in JavaScript, C++, or Java, call a small set of tracer functions to mark what should be drawn, and the platform replays your code as a controllable visualization — arrays light up, graph nodes get visited, charts grow, and a console logs whatever you print, all synchronized to the exact line of code that is running.
This guide covers everything you can do with Algorithm Visualizer: browsing the built-in algorithm library, writing your own visualizations with the tracer API, saving work to GitHub, embedding visualizations, and running the web app on your own machine.
Note
This repository (
algorithm-visualizer/algorithm-visualizer) is the web app — the React front end that renders visualizations and hosts the editor. It is one part of a larger system. The companionserverhandles GitHub sign-in and compiles/runs C++/Java code,algorithmsholds the side-menu catalog, and thetracers.*libraries provide the tracer API you call from your code. This guide tells you where each one comes into play.
1. Quick Start
The fastest way to use Algorithm Visualizer is the hosted website — no installation required.
- Open algorithm-visualizer.org in a modern browser.
- Pick an algorithm from the left sidebar (for example, Brute Force → Bubble Sort), or click Scratch Paper → New ... to start your own.
- Press Build (the wrench icon) to run the code and generate the visualization.
- Press Play, or use the ◀ / ▶ step buttons, to walk through the animation. The current line of code is highlighted as it runs.
Tip
The visualization is driven entirely by the code in the editor. Every time you change the code, press Build again to regenerate the animation.
Your first custom visualization
Click Scratch Paper → New .... The editor opens with a starter file. The default JavaScript skeleton looks like this:
// import visualization libraries {
const { Array2DTracer, Layout, LogTracer, Tracer, VerticalLayout } = require('algorithm-visualizer');
// }
// define tracer variables {
const array2dTracer = new Array2DTracer('Grid');
const logTracer = new LogTracer('Console');
// }
// define input variables
const messages = [
'Visualize',
'your',
'own',
'code',
'here!',
];
// highlight each line of messages recursively
function highlight(line) {
if (line >= messages.length) return;
const message = messages[line];
// visualize {
logTracer.println(message);
array2dTracer.selectRow(line, 0, message.length - 1);
Tracer.delay();
array2dTracer.deselectRow(line, 0, message.length - 1);
// }
highlight(line + 1);
}
(function main() {
// visualize {
Layout.setRoot(new VerticalLayout([array2dTracer, logTracer]));
array2dTracer.set(messages);
Tracer.delay();
// }
highlight(0);
})();
Press Build, then Play. You will see a grid whose rows highlight one at a time while a console prints each word.
Three ideas make the whole platform work, and they are all visible in that skeleton:
- Tracers are the visual objects (
array2dTracer,logTracer). You create them, then call methods like.set(),.selectRow(), and.println()to change what they show. Layout.setRoot(...)decides how the tracers are arranged on screen (here, stacked vertically).Tracer.delay()marks the boundary of one animation step. Everything you do between twodelay()calls is shown together, then the player pauses until you advance.
Important
Tracer.delay()is what makes the animation step. Without it, all your visual changes collapse into a single frame. Calldelay()at every point where you want the viewer to "see" the current state before moving on.
2. Installation (Running Locally)
You only need to install Algorithm Visualizer if you want to develop the web app itself or run it offline. For everyday use, the hosted site is enough.
Requirements
| Requirement | Detail |
|---|---|
| Node.js | >=10.15.3 (declared in package.json engines) |
| npm | Bundled with Node.js |
| Backend server | The server repo — run locally or use the remote one |
| Browser | Any modern evergreen browser (Chrome, Firefox, Safari, Edge) |
The web app talks to a backend for three things: GitHub sign-in, the algorithm catalog, and compiling/running C++ and Java. JavaScript visualizations run entirely in your browser and need no backend.
Install and run
Use the remote server (simplest)
-
Fork and clone the repository:
git clone https://github.com/<your-username>/algorithm-visualizer.git cd algorithm-visualizer -
Temporarily point the dev proxy at the public server. Edit
package.json(do not commit this change):- "proxy": "http://localhost:8080", + "proxy": "https://algorithm-visualizer.org", -
Install dependencies and start the dev server:
npm install npm start -
Open
http://localhost:3000/.
Run the server locally too
-
Clone and start
serverfollowing its own contributing guide. It listens on port8080. -
Leave
package.json's"proxy": "http://localhost:8080"unchanged. -
In the
algorithm-visualizerfolder:npm install npm start -
Open
http://localhost:3000/.
Expected output from npm start:
Compiled successfully!
You can now view @algorithm-visualizer/algorithm-visualizer in the browser.
Local: http://localhost:3000
On Your Network: http://192.168.x.x:3000
Note
The dev server proxies any request that isn't a static asset to the backend. That is why
/api/...calls (the algorithm catalog, GitHub auth, C++/Java compilation) work in development without CORS configuration — theproxyfield forwards them.
Run in Gitpod (zero local setup)
The repository ships a .gitpod.yml that clones and starts both the server and the web app automatically. Click the badge in the README, or open:
https://gitpod.io/#https://github.com/algorithm-visualizer/algorithm-visualizer
Gitpod starts the backend on port 8080 and the web app on port 3000, then notifies you when 3000 is ready.
3. Touring the Interface
The screen is divided into a header and three resizable panels.
┌────────────────────────────────────────────────────────────────┐
│ HEADER: Title ▸ Path [Save/Fork] [Delete] [Share] [Full] │
│ [Sign In] [Language ▾] [Build][Play][◀ ▮▮▮ ▶] Speed │
├──────────────┬─────────────────────────────┬───────────────────┤
│ NAVIGATOR │ VISUALIZATION VIEWER │ CODE EDITOR │
│ (sidebar) │ (the animation) │ (tabs + Ace) │
│ │ │ │
│ search... │ ┌──────────┐ │ code.js │
│ ▸ Category │ │ Grid │ │ 1 ... │
│ • Algo │ ├──────────┤ │ 2 ... │
│ ▸ Scratch │ │ Console │ │ (current │
│ Paper │ └──────────┘ │ line lit) │
└──────────────┴─────────────────────────────┴───────────────────┘
| Area | What it does |
|---|---|
| Navigator (left) | Searchable tree of built-in algorithms by category, plus your Scratch Paper gists, an API Reference link, and Fork me on GitHub. |
| Visualization Viewer (center) | Renders the current step of the animation. Pan by dragging; zoom with the mouse wheel (on graph/array views). |
| Code Editor (right) | The Ace code editor with file tabs. The line currently executing is highlighted during playback. |
| Header | Title/breadcrumb, save controls, language selector, sign-in, and the Player (Build / Play / step / speed). |
Resizing and collapsing panels
- Drag the divider between any two panels to resize them.
- Click the title bar (top-left breadcrumb) to collapse or expand the Navigator sidebar.
- Click Fullscreen in the header to enter full-screen mode.
Tip
The three panels remember their relative widths during a session. Make the Visualization Viewer wider when you are watching a large graph, and the editor wider when you are writing code.
4. Everyday Usage
4.1 Browsing and running built-in algorithms
- Use the search box at the top of the Navigator. Search is fuzzy: it matches on whole words and on initials, so typing
bfsfinds "Breadth-First Search" andbubblefinds "Bubble Sort". Hyphens and punctuation are ignored. - Click a category to expand it, then click an algorithm to open it. The URL changes to
/<categoryKey>/<algorithmKey>so you can bookmark or share it. - Press Build, then Play.
Built-in algorithms usually ship with multiple files: one or more code files, a README.md explaining the algorithm (rendered as a tab), and sometimes a data file. Switch between them using the tabs above the editor.
4.2 Choosing a language
Click the language selector (the star icon) in the header to switch between JavaScript, C++, and Java. Your choice is remembered in a cookie and decides which skeleton new files start from.
| Language | Where it runs | Backend required? |
|---|---|---|
JavaScript (.js) |
In your browser, in a Web Worker | No |
C++ (.cpp) |
Compiled and executed on the backend server | Yes |
Java (.java) |
Compiled and executed on the backend server | Yes |
Note
JavaScript is the only language that runs without a backend, because it executes in a sandboxed Web Worker in your browser. C++ and Java are sent to the server, compiled, and run there; the server returns the visualization commands. If C++/Java builds fail on a self-hosted setup, the server is the piece to check.
4.3 The Player: controlling playback
The Player lives in the header and controls the animation.
| Control | Icon | Action |
|---|---|---|
| Build | wrench | Run the current file's code and generate the visualization. Shows "Building…" with a spinner while working. |
| Play / Pause | ▶ / ❚❚ | Auto-advance through steps, or pause. Play wraps to the start when it reaches the end. |
| Previous step | ◀ | Step back one frame. |
| Next step | ▶ | Step forward one frame. |
| Progress bar | — | Shows current / total steps. Click or drag anywhere on it to jump to that point. |
| Speed | slider | A 0–4 slider controlling auto-play speed. |
The speed slider is exponential: the delay between steps is 4000 / e^speed milliseconds. At speed 0 each step lasts 4 seconds; at speed 4 it is about 73 milliseconds. The default is 2 (about 540 ms per step).
Tip
Use Previous / Next to study an algorithm one operation at a time, and the progress bar to jump straight to an interesting moment without watching the whole run.
4.4 Editing code
The editor is Ace with syntax highlighting per language and the tomorrow_night_eighties dark theme. Useful behaviors:
- Line highlighting — during playback, the editor highlights the line that produced the current step (driven by your
Tracer.delay()calls). - Auto-folding — when a file loads, blocks marked with a
// visualize {comment are folded shut so you can focus on the algorithm rather than the visualization plumbing. Click the fold marker to expand them. - Search — the Ace search box (
Ctrl/Cmd+F) is available inside the editor.
4.5 Working with files and tabs
- Add a file — click the + tab. A new file is created from the current language's skeleton, named
code.<ext>, thencode-1.<ext>, and so on to avoid collisions. - Rename a file — click a tab's name (it becomes editable) and type a new name. The file's language is inferred from its extension.
- Delete a file — open the file and click Delete File (it asks for confirmation).
- Markdown and JSON files — a
.mdfile renders as formatted text in the viewer; a.jsonfile can hold a raw visualization (see §6.2).
When you open an algorithm or scratch paper, the editor automatically selects the most relevant tab: a visualization.json if present, otherwise a file matching your current language, otherwise the first recognized code file.
5. Writing Visualizations — the Tracer API
This is the heart of Algorithm Visualizer. You instrument your algorithm with tracers, arrange them with a layout, and mark animation steps with delay. The platform records every tracer method you call and replays them as the animation.
Important
The tracer functions (
Array1DTracer,GraphTracer,Tracer.delay(),Layout.setRoot(), etc.) come from the visualization library for your language — the npmalgorithm-visualizerpackage for JavaScript, and the equivalenttracers.cpp/tracers.javalibraries for C++ and Java. The method names and behavior described below match what the platform interprets and draws. The canonical, always-current reference is the project wiki, linked as API Reference in the Navigator.
5.1 The three building blocks
// 1. Create tracers (the visual objects)
const tracer = new Array1DTracer('My Array');
// 2. Arrange them with a layout, and set the root
Layout.setRoot(new VerticalLayout([tracer]));
// 3. Change state, then call delay() to record a step
tracer.set([5, 2, 8, 1]);
Tracer.delay(); // <-- one animation frame
tracer.select(0);
Tracer.delay(); // <-- next frame
new XxxTracer(title)— creates a tracer with a panel title. The title is what appears above the panel in the viewer.Layout.setRoot(layout)— tells the viewer what to display. Pass a layout containing your tracers.Tracer.delay()— records the current state as one step. This is the single most important call: it is the difference between a static picture and an animation.
5.2 Layouts
Layouts arrange tracer panels. Two layouts are available, and they can be nested.
| Layout | Arrangement |
|---|---|
new VerticalLayout([...tracers]) |
Stacks panels top-to-bottom |
new HorizontalLayout([...tracers]) |
Places panels left-to-right |
Layout.setRoot(new VerticalLayout([
new HorizontalLayout([arrayTracer, graphTracer]),
logTracer,
]));
Each panel in a layout is independently resizable by dragging the divider between panels in the viewer. You can also add or remove children from a layout at runtime with layout.add(key), layout.remove(key), and layout.removeAll().
5.3 Tracer types at a glance
| Tracer | Visualizes | Renderer behavior |
|---|---|---|
Array1DTracer |
A 1-D array / list | A single row of cells; supports an attached chart |
Array2DTracer |
A 2-D grid / matrix | A table with row and column indices |
GraphTracer |
Nodes and edges | An SVG graph with circle/tree/random layouts |
ChartTracer |
A 1-D array as bars | A bar chart (Chart.js) |
ScatterTracer |
Series of [x, y] points |
A scatter plot (Chart.js) |
LogTracer |
Text output | A scrolling console |
MarkdownTracer |
Markdown text | Rendered Markdown (supports math images) |
All tracers share a constructor new XxxTracer(title) and a set(...) method to load data. The sections below document every method the platform interprets, grouped by tracer.
5.4 Array1DTracer
For one-dimensional arrays. Array1DTracer extends Array2DTracer, so it understands a single-row grid.
| Method | Description |
|---|---|
set(array1d) |
Loads the array. Each value becomes a cell. |
patch(x, v) |
Marks cell x as patched (changed), optionally setting its value to v. |
depatch(x) |
Clears the patched mark on cell x. |
select(sx, ex = sx) |
Highlights cells from index sx to ex (inclusive). Omit ex to select one cell. |
deselect(sx, ex = sx) |
Removes the highlight from cells sx–ex. |
chart(key) |
Mirrors this array's data into a linked ChartTracer (pass its key), or pass a falsy value to unlink. |
const D = require('algorithm-visualizer');
const tracer = new D.Array1DTracer('Array');
D.Layout.setRoot(new D.VerticalLayout([tracer]));
const arr = [5, 2, 8, 1, 9];
tracer.set(arr);
D.Tracer.delay();
// highlight a "current" element, then mark it as written
tracer.select(2);
D.Tracer.delay();
tracer.patch(2, 99);
D.Tracer.delay();
tracer.depatch(2);
tracer.deselect(2);
D.Tracer.delay();
Expected behavior:
Step 1: [5, 2, 8, 1, 9]
Step 2: cell 2 (value 8) highlighted
Step 3: cell 2 shown as patched, value 99
Step 4: marks cleared
Tip
Use select for "I am looking at this element" and patch for "I just wrote a new value here". Pairing them is the standard idiom for sorting visualizations: select the two elements being compared, patch them when you swap.
5.5 Array2DTracer
For matrices and grids. Indexing is (x, y) where x is the row and y is the column.
| Method | Description |
|---|---|
set(array2d) |
Loads a 2-D array. Each value becomes a cell. |
patch(x, y, v) |
Marks cell (x, y) as patched, optionally setting value v. |
depatch(x, y) |
Clears the patched mark on (x, y). |
select(sx, sy, ex = sx, ey = sy) |
Highlights the rectangle from (sx, sy) to (ex, ey). |
selectRow(x, sy, ey) |
Highlights row x from column sy to ey. |
selectCol(y, sx, ex) |
Highlights column y from row sx to ex. |
deselect(sx, sy, ex = sx, ey = sy) |
Clears a rectangular highlight. |
deselectRow(x, sy, ey) |
Clears a row highlight. |
deselectCol(y, sx, ex) |
Clears a column highlight. |
const D = require('algorithm-visualizer');
const grid = new D.Array2DTracer('Matrix');
D.Layout.setRoot(new D.VerticalLayout([grid]));
grid.set([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]);
D.Tracer.delay();
grid.selectRow(1, 0, 2); // highlight the whole middle row
D.Tracer.delay();
5.6 GraphTracer
For graphs and trees. Build the graph, choose a layout, and animate traversals with visit / leave.
Construction
| Method | Description |
|---|---|
set(adjacencyMatrix) |
Builds the graph from an N×N adjacency matrix. A non-zero entry [i][j] adds an edge i → j (its value becomes the weight if the graph is weighted). |
directed(isDirected = true) |
Sets whether edges are directed (default true). |
weighted(isWeighted = true) |
Sets whether edge/node weights are shown (default false). |
Nodes and edges
| Method | Description |
|---|---|
addNode(id, weight?, x?, y?) |
Adds a node with the given id. |
updateNode(id, weight?, x?, y?) |
Updates a node's properties. |
removeNode(id) |
Removes a node. |
addEdge(source, target, weight?) |
Adds an edge. |
updateEdge(source, target, weight?) |
Updates an edge. |
removeEdge(source, target) |
Removes an edge. |
findNode(id) / findEdge(source, target) |
Look up a node/edge. |
findLinkedEdges(source) |
All edges from a node. |
findLinkedNodeIds(source) / findLinkedNodes(source) |
Neighbors of a node. |
Traversal animation
| Method | Description |
|---|---|
visit(target, source?, weight?) |
Marks target (and the source → target edge, if given) as visited. Optionally updates the target's weight. |
leave(target, source?, weight?) |
Undoes a visit (decrements the visited count). |
select(target, source?) |
Marks target (and the edge) as selected. |
deselect(target, source?) |
Undoes a select. |
log(key) |
Links a LogTracer (by key) so each visit/leave/select is also printed to the console, e.g. 0 -> 1. |
Layout
| Method | Description |
|---|---|
layoutCircle() |
Arranges nodes evenly on a circle (default). |
layoutTree(root = 0, sorted = false) |
Tree layout rooted at root; set sorted to order children by id. |
layoutRandom() |
Scatters nodes randomly without overlap. |
const D = require('algorithm-visualizer');
const graph = new D.GraphTracer('Graph');
const log = new D.LogTracer('Log');
D.Layout.setRoot(new D.VerticalLayout([graph, log]));
graph.log(log); // mirror traversal events to the console
graph.set([
[0, 1, 1, 0],
[1, 0, 0, 1],
[1, 0, 0, 1],
[0, 1, 1, 0],
]);
graph.directed(false);
graph.layoutCircle();
D.Tracer.delay();
// breadth-first-ish visit
graph.visit(0);
D.Tracer.delay();
graph.visit(1, 0); // edge 0->1 lights up; log prints "0 -> 1"
D.Tracer.delay();
graph.visit(2, 0);
D.Tracer.delay();
Note
Nodes and edges track a visited count and a selected count rather than a boolean. That means
visitandleavenest correctly: callingvisittwice andleaveonce leaves the node still marked. This is what lets recursive algorithms (DFS, backtracking) highlight correctly as the call stack grows and shrinks.
5.7 ChartTracer and ScatterTracer
ChartTracerextendsArray1DTracer, so it has the sameset/select/patchAPI, but renders as a bar chart instead of a row of cells. It is most useful linked to anArray1DTracerviaarrayTracer.chart(chartKey), so the same data appears both as cells and as bars.ScatterTracerextendsArray2DTracerand renders series of[x, y]points as a scatter plot. Each row of the 2-D data is drawn as a separate colored series.
const D = require('algorithm-visualizer');
const array = new D.Array1DTracer('Values');
const chart = new D.ChartTracer('Chart');
D.Layout.setRoot(new D.VerticalLayout([array, chart]));
array.chart(chart); // keep the chart in sync with the array
array.set([3, 1, 4, 1, 5, 9, 2, 6]);
D.Tracer.delay();
5.8 LogTracer
A scrolling text console — ideal for printing pseudo-output, counters, or decisions.
| Method | Description |
|---|---|
set(log) |
Replaces the console contents. |
print(message) |
Appends text without a newline. |
println(message) |
Appends text followed by a newline. |
printf(format, ...args) |
Appends printf-style formatted text (via sprintf). |
const D = require('algorithm-visualizer');
const log = new D.LogTracer('Console');
D.Layout.setRoot(new D.VerticalLayout([log]));
log.println('Starting search');
log.printf('Checking index %d (value = %d)', 3, 42);
D.Tracer.delay();
5.9 MarkdownTracer
Renders Markdown — useful for explaining the algorithm alongside the animation.
| Method | Description |
|---|---|
set(markdown) |
Renders the given Markdown string. |
Markdown rendering supports embedded math images from CodeCogs and Wikimedia (they are recolored to be readable on the dark theme), and renders inline HTML.
Caution
The Markdown and Log renderers display content as HTML. Only run scratch papers you trust — a malicious visualization could embed unsafe markup. See the Admin Guide's security section for details.
5.10 Putting it together: a complete bubble sort
const { Array1DTracer, Layout, LogTracer, Tracer, VerticalLayout } = require('algorithm-visualizer');
const tracer = new Array1DTracer('Array');
const logger = new LogTracer('Console');
Layout.setRoot(new VerticalLayout([tracer, logger]));
const arr = [5, 2, 8, 1, 9, 3];
tracer.set(arr);
Tracer.delay();
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
tracer.select(j, j + 1); // comparing two neighbors
Tracer.delay();
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
tracer.patch(j, arr[j]); // show the swap
tracer.patch(j + 1, arr[j + 1]);
Tracer.delay();
tracer.depatch(j);
tracer.depatch(j + 1);
logger.println(`Swapped indices ${j} and ${j + 1}`);
}
tracer.deselect(j, j + 1);
}
}
Tracer.delay();
logger.println('Done');
6. Workflows
6.1 Saving your work to GitHub (Scratch Paper)
Scratch papers are stored as GitHub Gists, so your visualizations live in your own GitHub account.
- Click Sign In in the header and authorize with GitHub. (Sign-in is handled by the backend server.)
- Edit your scratch paper.
- Click Save. The first save creates a new secret Gist; subsequent saves update it. The URL becomes
/scratch-paper/<gistId>. - Your saved scratch papers appear under Scratch Paper in the Navigator on every device you sign in from.
| Button | When it appears | Action |
|---|---|---|
| Save | You own this scratch paper (or it's brand new) | Create or update the Gist |
| Fork | The scratch paper belongs to someone else | Copy it into your account, then save |
| Delete | You own a saved scratch paper | Delete the Gist (with confirmation) |
| Share | Always | Share the current URL to Facebook |
Note
Each Algorithm Visualizer scratch paper Gist includes a marker file named
algorithm-visualizer. That is how the app recognizes which of your Gists are scratch papers. Don't delete that file from the Gist.
Warning
If you have unsaved changes and try to navigate away or close the tab, the app warns you ("Are you sure you want to discard changes?"). Save first to avoid losing work.
6.2 Rendering a raw visualization from JSON
If you have a precomputed command stream, save it as a .json file (or open a visualization.json). The platform renders it directly without running any code — useful for embedding output from tools that generate the command format.
6.3 Embedding a visualization
Opening /scratch-paper/new?visualizationId=<id> loads a stored visualization by id from the backend's visualization API and displays it as an untitled scratch paper. This is the mechanism used to share a one-off generated visualization via a link.
6.4 Contributing a visualization to the public library
Visualizations shown in the sidebar live in the separate algorithms repository. To add your algorithm to the public side menu, follow that repo's contributing guidelines — a scratch paper alone stays private to your Gists.
7. Advanced Usage
7.1 Deep-linking and URLs
| URL | Opens |
|---|---|
/ |
Home (the project README) |
/<categoryKey>/<algorithmKey> |
A built-in algorithm |
/scratch-paper/new |
A fresh scratch paper in your current language |
/scratch-paper/new?visualizationId=<id> |
An embedded stored visualization |
/scratch-paper/<gistId> |
A saved scratch paper (your own or someone else's) |
These URLs are stable and shareable — bookmark an algorithm or send a colleague a direct link to your scratch paper.
7.2 Tuning the animation
- Granularity — the number of
Tracer.delay()calls determines how many steps your animation has. Moredelay()calls = finer-grained, slower stepping. Place them where the state changes that matter. - Line highlighting — because the highlighted line is tied to where
delay()was called, puttingdelay()right after the meaningful line keeps the editor highlight in sync with the action. - Multiple panels — combine an
Array1DTracer, aChartTracer, and aLogTracerin one layout to show the same data three ways at once.
7.3 Keyboard and mouse interactions in the viewer
- Pan — click and drag inside an array or graph panel.
- Zoom — scroll the mouse wheel over an array or graph panel (zoom range is roughly 0.05×–20×).
- Drag graph nodes — in a
GraphTracerpanel, drag a node to reposition it.
8. How It Works (Concepts)
You do not need this section to use the platform, but it explains why the API is shaped the way it is.
When you press Build, the platform runs your code through the visualization library for your language:
- JavaScript runs in a sandboxed Web Worker in your browser — no backend needed.
- C++ / Java are sent to the backend server, compiled, and executed there.
- Markdown / JSON files are handled directly in the browser.
As your code runs, every tracer method call is recorded as a command (which object, which method, which arguments). The result is a flat list of commands. Each Tracer.delay() becomes a divider that splits the list into chunks — and each chunk is exactly one step of the animation.
Your code ──► command list ──► split at every delay() ──► steps
new Array1DTracer('A') [create A]
A.set([3,1,2]) [A.set ...]
Tracer.delay() ─────────────────────── step 1 boundary
A.select(0) [A.select 0]
Tracer.delay() ─────────────────────── step 2 boundary
When you move the player to a step, the Visualization Viewer replays the commands up to that point onto its tracer and renderer objects, then draws them. Stepping backward simply replays from the beginning up to the new position. That replay model is why scrubbing the progress bar is instant and why every step is perfectly reproducible.
Tip
This is also why your algorithm should be deterministic for a clean visualization: the same code is replayed the same way every time. Avoid relying on wall-clock time or unseeded randomness if you want the animation to match the highlighted code exactly.
9. Troubleshooting
Error: Language Not Supported
Cause: You pressed Build on a file whose extension isn't js, cpp, java, md, or json.
Solution: Rename the file to use a supported extension, or switch to a supported language.
Prevention: Create new files with the + tab, which uses the current language's skeleton and extension.
Build spins forever or fails for C++/Java
Cause: C++ and Java are compiled on the backend server. If the server is unreachable, misconfigured, or the public server is down, the build cannot complete. (Community requests such as #361, #335, and #792 revolve around getting C/C++ working locally.)
Solution: For local development, either run the server locally or point the proxy at the public server. JavaScript visualizations always work without a backend — use JS to confirm the rest of the app is fine.
Prevention: Verify the backend is running on port 8080 (or your proxy target is reachable) before building C++/Java.
Sign In does nothing / authentication fails
Cause: GitHub sign-in is handled by the backend, and authentication has been reported broken in some deployments (#303). A frozen or expired backend can't complete the OAuth flow. Solution: Ensure you reached the site over HTTPS and that the backend's GitHub OAuth credentials are configured. You can use all visualization features except saving without signing in. Prevention: Sign-in requires a correctly configured server; the hosted site handles this for you.
Browser warns about an expired certificate on algorithm-visualizer.org
Cause: The hosted site's TLS certificate has expired at times (#802, #381). Solution: This is a hosting/operations issue, not something you can fix from the app. Run the app locally if you need uninterrupted access.
My animation is just one frame — nothing moves
Cause: You didn't call Tracer.delay(), so all your changes collapse into a single step.
Solution: Add Tracer.delay() after each state change you want to see animated.
Prevention: Follow the skeleton's pattern — delay() inside the loop, after the visual update.
npm start warns about the Sass legacy JS API
Cause: The project uses node-sass, which emits legacy-API deprecation warnings on newer toolchains (#805).
Solution: The warnings are non-fatal; the app still builds and runs. They can be ignored for normal use.
npm start exits or can't find the backend
Cause: The dev proxy in package.json points at a backend that isn't running.
Solution: Start the local server on 8080, or temporarily set the proxy to https://algorithm-visualizer.org (don't commit that change).
Prevention: Decide up front whether you're using a local or remote server (see §2).
A built-in algorithm won't load ("Algorithm Not Found")
Cause: The category/algorithm key in the URL doesn't exist in the catalog, or the catalog API is unreachable.
Solution: Pick the algorithm from the Navigator instead of typing the URL. Check that the backend's /api/algorithms endpoint is reachable.
10. FAQ
Q: Do I need to install anything to use Algorithm Visualizer? No. Use algorithm-visualizer.org directly. Install locally only if you want to develop the app or work offline.
Q: Which languages can I write visualizations in? JavaScript, C++, and Java. JavaScript runs in your browser; C++ and Java are compiled and run on the backend server.
Q: Where is my scratch paper saved?
As a secret GitHub Gist in your own account (it includes a marker file named algorithm-visualizer). Sign in to see all your scratch papers in the Navigator.
Q: Can I use a visualization someone else made? Yes. Open their scratch paper URL and click Fork to copy it into your account, then edit and save your own version.
Q: What does Tracer.delay() do?
It marks one animation step. Everything between two delay() calls is shown together as a single frame.
Q: Why is the current line of code highlighted?
Each step remembers the line where its delay() was called, so the editor highlights what the algorithm is doing right now.
Q: How do I make the animation slower or faster? Use the Speed slider in the Player, or use Previous / Next to step manually.
Q: How do I show two views of the same data?
Create both tracers (e.g. an Array1DTracer and a ChartTracer), put them in a layout, and link them with arrayTracer.chart(chartKey).
Q: Can I add my algorithm to the sidebar everyone sees?
Yes — contribute it to the algorithms repository. Scratch papers stay private to your Gists.
Q: My graph traversal highlights don't clear correctly. Why?
Visited and selected states are reference-counted. Make sure every visit is balanced by a leave (and every select by a deselect) so nested/recursive traversals unwind cleanly.
Q: Is there a full method reference? Yes — the API Reference link in the Navigator points to the project wiki, which documents each tracer per language.
Q: Does Algorithm Visualizer support custom colors / hashmaps / quantum algorithms?
These are open community requests (#181, #794, #790) — not currently built in. You can model a hashmap today with an Array1DTracer (buckets) plus a LogTracer.
11. Reference
Tracer types and base classes
| Tracer | Extends | Constructor |
|---|---|---|
Tracer |
— | new Tracer(title) |
Array2DTracer |
Tracer |
new Array2DTracer(title) |
Array1DTracer |
Array2DTracer |
new Array1DTracer(title) |
ChartTracer |
Array1DTracer |
new ChartTracer(title) |
ScatterTracer |
Array2DTracer |
new ScatterTracer(title) |
GraphTracer |
Tracer |
new GraphTracer(title) |
LogTracer |
Tracer |
new LogTracer(title) |
MarkdownTracer |
Tracer |
new MarkdownTracer(title) |
Layouts and globals
| Symbol | Purpose |
|---|---|
Layout.setRoot(layout) |
Sets what the viewer displays |
new VerticalLayout([...]) |
Stack panels vertically |
new HorizontalLayout([...]) |
Place panels horizontally |
Tracer.delay() |
Record one animation step |
Supported file types
| Extension | Editor mode | Runs where |
|---|---|---|
.js |
JavaScript | Browser (Web Worker) |
.cpp |
C/C++ | Backend server |
.java |
Java | Backend server |
.md |
Markdown | Browser (rendered) |
.json |
JSON | Browser (raw visualization) |
Player controls
| Control | Effect |
|---|---|
| Build | Run code → generate steps |
| Play / Pause | Auto-advance / stop |
| ◀ / ▶ | Step back / forward |
| Progress bar | Jump to step (current / total) |
| Speed (0–4) | Delay per step = 4000 / e^speed ms |
Default ports (local development)
| Port | Service |
|---|---|
3000 |
The web app (this repo, npm start) |
8080 |
The backend server (proxy target) |
Related repositories
| Repo | Role |
|---|---|
algorithm-visualizer |
The web app (this repository) |
server |
Sign-in, algorithm catalog, C++/Java compilation |
algorithms |
The public side-menu visualizations |
tracers.* |
Per-language visualization libraries (the tracer API) |