Recursion Tree Visualizer
Visualize recursive call trees step by step
Updated
What is the Recursion Tree Visualizer?
The Recursion Tree Visualizer runs a named, self-recursive JavaScript function with the arguments you provide and displays the recorded calls as an animated tree. It is designed for learning and experimenting with functions that fit the tool's instrumentation limits.
Step through the recorded calls and returns to see how the call tree and call stack change over the run.
Built-in presets include Fibonacci, factorial, the Euclidean GCD, Pascal's Triangle, Tower of Hanoi, and powers of two. You can also enter a self-recursive function declaration.
Each node is color-coded by recursion depth so you can immediately see how deep the call chain goes. Return values appear beneath their nodes once a call completes. The step slider and keyboard shortcuts (arrow keys for single steps, spacebar to play/pause, Home/End to jump) give you full control over the pace.
The visualization supports pan and zoom so large trees remain navigable. Drag to pan the canvas, scroll to zoom in or out, and use the Fit View button to auto-frame the entire tree in the viewport.
You can export the recorded call data as JSON for further inspection.
Your code runs in the browser and is not isolated in a security sandbox. Only run code you trust; do not paste untrusted code into the tool.
How it works
1. Code instrumentation
When you click Execute & Visualize, the tool parses your function declaration to extract its name. It then performs two source-level transformations: the original declaration is renamed to a private alias (e.g., fib becomes __orig_fib), and every recursive call to the original name is replaced with a call to a tracking wrapper named __tracked.
2. Execution limits
The rewritten source is compiled with JavaScript's new Function and runs in the browser page; this is not a security sandbox. The tool adds two configurable limits to tracked recursive calls:
- Max Depth -- if the call stack exceeds this depth, execution stops with a clear error message suggesting you check your base case.
- Max Calls -- if the total number of recorded calls exceeds this limit, execution halts to prevent the browser from freezing.
These limits can stop tracked recursion, but they do not prevent other user code from running or guarantee that the page cannot become unresponsive. Run only code you trust.
3. Call recording
Every time __tracked is invoked, it records an entry containing a unique ID, the parent call's ID, the arguments, and the current stack depth. When the call returns, the recorded entry is updated with the return value. The result is a flat array of CallRecord objects that captures the full execution trace.
4. Tree construction
The flat call records are assembled into a hierarchical tree. Each record's parentId links it to its caller. The root node has no parent. Children are attached in the order they were called, preserving the left-to-right structure that matches how the recursion unfolds.
5. Layout algorithm
A bottom-up, width-packing algorithm assigns horizontal positions:
- Leaf nodes are sized to their content width.
- Each parent's subtree width is the sum of its children's widths plus the horizontal gap between siblings, or the parent's own content width -- whichever is larger.
- Starting from the root, children are centered under their parent within the allocated subtree width.
This produces a compact, non-overlapping layout for trees of any shape.
6. Step generation
The tool replays the execution trace to generate an interleaved list of call and return steps. A call step appears when a node first enters the tree; a return step appears when that node's value is computed. The order matches the actual program execution, including depth-first traversal and backtracking.
7. Animated playback
At any step index, the tool computes which nodes are visible, which have returned, and which is currently active. The SVG tree renders only the nodes present at that step, with visual cues:
- Active node has an amber glow and highlighted edge.
- Returned nodes become muted with dashed edges.
- Depth coloring distinguishes levels across the full palette.
- Return values appear beneath nodes once they complete.
The step slider, playback controls, and keyboard shortcuts all operate on this step-index model, making the animation fully reversible and seekable.
Examples
Visualize Fibonacci recursion tree
See every branch of fib(7) unfold step by step, from the initial call down to each base case return.
function fib(n) { if (n <= 1) return n; return fib(n - 1) + fib(n - 2); } args: 7Tree with 41 nodes, max depth 6, final result 13, animated call-by-call playback with depth coloringTrace the Euclidean GCD algorithm
Watch gcd(48, 18) recurse through modulo reductions in a linear chain until it reaches the base case.
function gcd(a, b) { if (b === 0) return a; return gcd(b, a % b); } args: 48, 18Linear chain of 4 nodes, max depth 3, final result 6, each step shows argument pair shrinkingExplore Pascal's Triangle binomial coefficient
Compute C(5,3) recursively and observe the branching pattern that mirrors the combinatorial identity.
function pascal(n, k) { if (k === 0 || k === n) return 1; return pascal(n - 1, k - 1) + pascal(n - 1, k); } args: 5, 3Branching tree with 19 nodes, max depth 4, final result 10, overlapping subproblems visibleFrequently asked questions
What JavaScript features does the Recursion Tree Visualizer support?
What JavaScript features does the Recursion Tree Visualizer support?
The tool supports standard JavaScript function declarations with named recursion. You can use numbers, strings, booleans, and arrays as arguments. Control flow constructs like if/else, ternary operators, and arithmetic all work normally. The tool does not support arrow functions, async/await, or module imports -- the function must be a self-contained function name(params) { ... } declaration.
Why does my function throw a "Maximum recursion depth exceeded" error?
Why does my function throw a "Maximum recursion depth exceeded" error?
This means tracked recursion exceeded the configured depth limit. Check that your function has a reachable base case or reduce the input. Increasing the limit can produce a larger tree and may make the page slower.
Can I visualize mutual recursion (two functions calling each other)?
Can I visualize mutual recursion (two functions calling each other)?
Not currently. The tool instruments a single named function and replaces self-recursive calls. Mutual recursion between two or more functions requires a different instrumentation strategy. For now, rewrite the logic as a single function with an extra parameter to distinguish the roles, or visualize each function separately.
Is my code sent to a server?
Is my code sent to a server?
The code is executed in your browser using new Function, but it is not isolated in a security sandbox. Only run code you trust. Do not paste untrusted code into the tool.
How large a recursion tree can the tool handle?
How large a recursion tree can the tool handle?
The tool caps the configurable limits at 50 for depth and 5,000 calls. Large trees may still take time to build or render; the limits do not prevent all code from blocking the page. Reduce the input if the visualization becomes slow.
What do the colors in the tree represent?
What do the colors in the tree represent?
Each recursion depth level gets a distinct color from a rotating ten-color palette. Depth 0 is blue, depth 1 is purple, depth 2 is pink, and so on. The small numeric badge on each node's corner also shows the exact depth. This makes it easy to spot deep recursion chains and compare branching patterns across algorithms.
Can I export or save the visualization?
Can I export or save the visualization?
Yes. After execution, Export JSON downloads the recorded calls with their IDs, parent IDs, arguments, depth, and return values.
How do I control the playback speed?
How do I control the playback speed?
Use the Speed slider below the playback controls. Dragging it right increases the frame rate. You can also step through manually with the left/right arrow keys on your keyboard, press spacebar to toggle play/pause, or use Home and End to jump to the first or last step. The step slider lets you drag to any point in the animation instantly.
Why are some nodes shown with dashed edges and muted colors?
Why are some nodes shown with dashed edges and muted colors?
Dashed, muted nodes have already returned -- their computation is complete and their return value is known. This visual distinction helps you focus on the currently active branch of the recursion. You can toggle the display of return values using the Return values switch.
What does the call stack panel show?
What does the call stack panel show?
The call stack panel on the right side of the tree displays the current execution stack at any animation step. The topmost entry is the active function call, and entries below it are the callers waiting for results. Each entry shows the depth number, its arguments, and a colored bar matching the depth palette. This mirrors what you would see in a debugger's call stack window.
Related tools
More utilities you might find handy.
Binary Search Visualizer
Visualize binary search algorithm step by step
Regex Visualizer — Railroad Diagram Generator for Regular Expressions
Visualize common JavaScript regex syntax with a railroad diagram, token explanations, and a match tester. Includes a heuristic warning for some nested quantifiers.
Shape Drawer
Create and edit geometric shapes with precise measurements, live calculations, and export to SVG, CSS, or HTML