Algorithmic Art Frames.
CatalogContribute

Add your own algorithm.

Every poster in the catalog is a self-contained plugin: a title, a tagline, a pseudocode snippet, and a function that draws an SVG diagram. Add one new module and register it, and it never requires touching the renderer, the API, or this frontend.

The contract

Every algorithm module exposes one module-level PLUGIN, an instance of AlgorithmPlugin (backend/app/algorithms/base.py):

@dataclass(frozen=True)
class AlgorithmPlugin:
    slug: str            # kebab-case, e.g. "binary-search"
    title: str           # e.g. "Binary Search"
    tagline: str         # one line, e.g. "Halve the search space every step."
    category: AlgorithmCategory  # pick one, don't invent a new string
    pseudocode: list[str]
    draw: Callable[[RenderContext], str]
    accent: str           # signature hex color, e.g. "#FF8A3D"
    author: str | None = None  # optional, shown bottom-right when enabled
    date: str | None = None    # optional, e.g. "2026-08-26"

category must be one of AlgorithmCategory (also in base.py), so the catalog's categories can't fragment into near-duplicates ("ml" vs "machine-learning") as more algorithms get added. Need one that doesn't fit? Add a new member to the enum in the same PR rather than falling back to a raw string.

class AlgorithmCategory(str, Enum):
    SEARCH = "search"
    SORTING = "sorting"
    GRAPH = "graph"
    GAME_THEORY = "game-theory"
    CRYPTOGRAPHY = "cryptography"
    COMPRESSION = "compression"
    STREAMING = "streaming"
    PROBABILITY = "probability"
    OPTIMIZATION = "optimization"
    MACHINE_LEARNING = "machine-learning"
    SIGNAL_PROCESSING = "signal-processing"
    LINEAR_ALGEBRA = "linear-algebra"
    GRAPHICS = "graphics"
    STRINGS = "strings"

draw(ctx) gets a render context (theme + canvas size) and returns raw SVG markup. The shared new_canvas() helper lays out the title/tagline/pseudocode and hands back a content box to draw into:

def draw(ctx: RenderContext) -> str:
    dwg, box = new_canvas(
        ctx,
        title="Binary Search",
        tagline="Halve the search space every step.",
        pseudocode=PSEUDOCODE,
    )
    # ... draw into `box` using dwg.rect / dwg.text / dwg.line ...
    return dwg.tostring()

Steps

01

Copy the template

Copy backend/app/algorithms/_template.py to a new snake_case file, e.g. dijkstra.py.

cp backend/app/algorithms/_template.py backend/app/algorithms/dijkstra.py
02

Draw your diagram

Fill in PSEUDOCODE and draw(ctx). Use new_canvas() for the title/tagline/pseudocode scaffolding, then draw into the returned ContentBox with ctx.theme colors so it works in both dark and light.

03

Register it

Import your module in backend/app/algorithms/__init__.py and add it to the _MODULES tuple. REGISTRY builds itself from that list.

04

Test it

Add your slug to EXPECTED_SLUGS in backend/tests/test_algorithms.py, then run the checks.

pytest
ruff check .

No frontend changes needed: the catalog and detail pages fetch /api/algorithms at request time, so your new poster shows up automatically once it's registered.

Full reference

The complete write-up, plus the copy-pasteable template file, lives in the repo.

View CONTRIBUTING.md