Veins chase auxin sources across a growing leaf, pressed onto a herbarium sheet.
Auxin sources are dart-thrown into the blade wherever there is room, and vein nodes grow one step at a time toward the sources that pull on them: the space colonization algorithm of Runions and colleagues. In open venation each source pulls only its nearest node and the veins form a tree with free endings; in closed venation it pulls every node in its relative neighbourhood and dies only when all of them arrive, so veins fuse into loops. An auxin maximum at the blade tip (and at each lobe tip) drags the primary veins along as the blade grows at its margin, then the blade stretches uniformly, which opens gaps between the veins for finer tertiary veins to fill, and each vein's width follows the pipe model, so the midrib and secondary veins thicken on their own. Eight leaf archetypes (cordate, palmate, lanceolate and more) come from one polar outline with lobes, a drip tip and teeth laid out by arc length.
Try it. Click the sheet to grow a new species. Drag the Width, Lobes and Teeth sliders (a dashed outline previews the shape) and switch between open and closed venation. Hover the leaf to backlight it on a lightbox. Space grows the next species, V toggles venation and the arrow keys change width and lobes.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a leaf that grows its own veins with the space colonization algorithm, using JavaScript and the HTML canvas element. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Make a canvas that fills the window, stays sharp on high-DPI screens (scale by devicePixelRatio), and has a cream paper background.
- Describe the leaf outline as a function: an ellipse with its base at the petiole is fine. Write an inside(x, y) test for it.
- Scatter about 600 auxin sources inside the leaf with dart throwing: reject a random point if it is closer than a birth distance to any other source.
- Start with one vein node at the base. Each step, give every source the vein node nearest to it. Every node that was picked grows a new child node one small step toward the average direction of its sources.
- Remove a source as soon as any vein node comes within a kill distance of it. Stop when no sources are left.
- Draw each node as a line to its parent, and animate a few steps per frame with requestAnimationFrame so the veins visibly grow.
Once that works, make it beautiful:
- Grow the leaf too: start the outline small, scale it up a little every step, and keep dart throwing new sources into the new space so veins follow the margin outward.
- Use the pipe model for vein width: tips have width 1 and each node's width is (sum of child widths cubed) to the one-third power. Draw thick veins first and batch lines by width.
- Fill the blade with a mottled green and draw the veins pale, like a pressed herbarium specimen, with a small handwritten-style label.
Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as closed venation with loops (let a source attract every node in its relative neighbourhood), lobed and toothed outlines, or a backlit lightbox view that shows the veins dark against glowing tissue.