As tscircuit grows more people have been interested in contributing to fundamental algorithms for autorouting, packing, graph problems or complex domain-specific spatial problems. I’ve seen people both struggle to understand how to contribute as well as write/vibe sloppy unmaintainable code for algorithms.
The fundamental problem: how you’d intuitively write an algorithm, how AI writes algorithms and how you’re taught in school to write is a terrible approach for new algorithm development.
How to make an algorithm the wrong way
Here’s how most people would write a new algorithm:
Dream up a concept
Write/vibe a function that implements the algorithm
Console log some simple inputs/outputs to verify correctness
This approach is tragic because it creates algorithms that 1) only the original developer understands (if they can even remember) 2) leads to building goliath fragile functions with no visible intermediary results
PVISA: Pipeline, Visualize, [be] Iterative, Snapshot, Approximate
PVISA is an approach to algorithm building that I noticed would consistently work and be maintainable, even if I vibe-coded parts of the algorithm. It was resilient to stupid mistakes and partial overhauling. It allowed contributors to come in and build alongside me. Let’s go through each part:
Pipeline - Always have a top-level Pipeline that moves your data through different sub-algorithms. EVERY COMPLEX ALGORITHM HAS MANY SUB-ALGORITHMS! It is a mistake to think of an algorithm has a single function or a single stage. Every obvious algorithm is already packaged or in a standard library, if there is any complexity to what you’re doing, you need to have a pipeline.

Visualize - You should visualize EVERY ITERATION of your algorithm. There should be no bug that is not immediately obvious or cannot be pointed to with a visual. When debugging, you should be able to “point to the iteration” that does something you didn’t expect
Be Iterative - Any “for loop” that contains complex behavior should be BROKEN. You must design everything to work in iterations where each iteration can be visualized. I love object-oriented classes with a `.step()` function and some state for managing this. At any point, you can call `.visualize()` to get a visualization for your current iteration. IT WILL STRETCH YOUR BRAIN TO REFACTOR TO THIS STYLE (but you must do it to succeed!)
Snapshot - You must take snapshots of your algorithms output in a way that is understandable to humans. Humans generally forget/are bad at looking at numbers, so you should use Visual Snapshot Testing (SVG outputs) to allow humans to see the impact of changes in pull requests.
Approximate - Most non-trivial algorithms are hard to implement optimally on the first go. Build your algorithms to tolerate non-optimality, this often means introducing stages just to “improve” the output of prior stages. This is good! For our autorouter, we have stages that “straighten-out” our routes (shown below)
Building Algorithms like Web Applications
We created the graphics-debug module (MIT open-source) for the explicit purpose of visualizing 2D algorithms. Input a simple JSON object and get an interactive visualization. Use the objects to produce SVGs for visual snapshot tests.
Just like code that cannot be tested is bad and must be restructured such that it can be tested, code that cannot be visualized is bad and should be restructured.
Develop algorithms with the intent to build a web interface to configure, explore and test it. Never develop algorithms in such a way that intermediary outputs can’t be explored with a web interface!
As you build your algorithm, the visualization will get more and more robust. The web interface will allow more parameters to be configured. You’ll have more filters and configurations to explore deeper and download intermediary outputs.
Use React Cosmos for Building Algorithm Web Apps
We use React Cosmos to quickly create web apps for algorithms. We do this because…
It’s nearly zero effort, just create `*.fixture.tsx` files that export a React component and you have a new page (remember, every Graphics Debug object can become interactive with the <InteractiveGraphics /> component from the graphics-debug module!)
Cosmos apps can easily be deployed into preview environments with Vercel
Claude/ChatGPT algorithm React algorithm visualizations can generally just be downloaded and given the extension .fixture.tsx and they’ll work perfectly!
The Progression of an Algorithm Web App
The web app for an algorithm usually sucks at first, only exposing the most basic operations: the visualization and the step function. Over time, you add additional debugging and visualizations to help with understanding. Here are three algorithms in different stages of development:



The Solver Interface
In tscircuit code, “Solver” always means a class with the following methods:
`step()` - Iterate the algorithm just once
`solve()` - Step until the algorithm has been solved or fails
`visualize()` - Get a graphics-debug object for the current iteration that can be converted to an SVG or given as a prop to <InteractiveGraphics />
`.solved` / `.failed` / `.iterations` to track the algorithms progress
This is all you need to build any algorithm! This is a tried and true pattern that has allowed me to build massive algorithms! Don’t skip the visualize(), and don’t have single-step solvers (always iterate and write good visualizations for each iteration). Everything is 100x easier when you use this pattern!
Nesting Algorithms without breaking the rules
You will NEED to nest algorithms. This is critical for orchestrating a large algorithm. Sometimes when you’re iterating, you’re just calling the `.step()` function of a subsolver! Often your `visualize()` function will just be returning the result of a sub-solver, and that’s totally ok!
Use Claude.ai for Prototyping, then Claude Code to integrate
Claude.ai (the website chat for Claude) is fantastic for creating quick visualizations and implementation prototypes of sub-algorithms. You can then copy these visualizations into a fixture file and ask Claude Code to integrate into your codebase. This allows you to build up the algorithm bit-by-bit!
Another prototype built with Claude.ai, this time I passed in the types of the objects from the project so that the algorithm would have some extra understanding of the input problem and output something that was easier for Claude Code to integrate.
Want to help us build algorithms?
tscircuit is MIT open-source and we’re currently working on many autorouting, auto-layout and packing algorithms. Join our discord to learn more!