HomeArticlesGenerative Art

L-Systems: Growing Fractals From a Grammar and a Turtle

A handful of rewriting rules and a turtle that only knows forward, turn left and turn right are enough to grow ferns, trees, dragon curves and snowflakes.

mysimulator teamUpdated June 2026≈ 7 min read▶ Open the simulation

Rewriting an alphabet, generation by generation

An L-system (Lindenmayer system) is a formal grammar: an alphabet of symbols, a starting string called the axiom, and a set of production rules that say what each symbol should be replaced by. Aristid Lindenmayer introduced them in 1968 to model the growth of algae. The crucial difference from a Chomsky grammar used to parse programming languages is that every symbol in the string is rewritten simultaneously, generation after generation, rather than one substitution applied at a time — which mirrors how every cell in a growing organism divides at once.

axiom: F
rule:  F -> F+F--F+F
angle: 60 degrees

gen 0: F
gen 1: F+F--F+F
gen 2: F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F   (Koch-style curve)
live demo · a fractal curve unfurling generation by generation● LIVE

Turtle graphics: turning symbols into geometry

The rewritten string means nothing until it is drawn, and that is the job of a turtle that walks across the canvas obeying each symbol in order: F moves forward while drawing a line, f moves forward without drawing, + and - turn the turtle left or right by a fixed angle, and [ / ] push and pop the turtle's position and heading onto a stack. That stack is what turns a single string into a branching structure: the turtle draws one branch, brackets back to the fork point, and starts the next branch from exactly where it left off.

for symbol in string:
  if symbol == 'F': drawLineForward(stepLength);
  if symbol == 'f': moveForward(stepLength)
  if symbol == '+': heading += angle
  if symbol == '-': heading -= angle
  if symbol == '[': stack.push({pos, heading})
  if symbol == ']': {pos, heading} = stack.pop()

Stochastic and parametric extensions

A plain L-system is exactly self-similar, which looks geometric rather than organic. Stochastic L-systems fix that by giving several possible replacements for a symbol, each with its own probability, so no two branches unfold identically — this is how Barnsley's fern gets its natural, irregular look from a purely random rule choice at every step. Parametric L-systems attach numeric parameters to symbols (branch length, thickness, angle) that shrink or vary with each generation, letting a tree taper realistically as it grows outward, and context-sensitive variants let a symbol's rewrite depend on its neighbours, approximating how real plant hormones signal growth between adjacent cells.

Famous examples and their rules

Koch snowflake   F->F+F--F+F            angle 60
Dragon curve     X->X+YF+  Y->-FX-Y     angle 90
Sierpinski tri.  F->G-F-G  G->F+G+F     angle 60
Barnsley fern    (parametric, 4 stochastic affine transforms)
Hilbert curve    A->-BF+AFA+FB-  B->+AF-BFB-FA+  angle 90

Why it scales: complexity from short strings

A rule that replaces one symbol with k symbols makes the string grow roughly like k^n after n generations — exponential growth from a rule you could write on a napkin. That is the entire appeal of the model: a few characters of grammar, applied recursively, generate the same kind of branching self-similarity biologists see in real ferns, bronchial trees and river deltas. Prusinkiewicz and Lindenmayer catalogued this connection thoroughly in The Algorithmic Beauty of Plants, still the standard reference for anyone building a botanically plausible L-system.

Frequently asked questions

What do the square brackets in an L-system rule mean?

They tell the turtle to save or restore its state. [ pushes the current position and heading onto a stack; ] pops the stack, returning the turtle to that saved position and heading. That is how a single string produces a branching tree instead of one continuous line: the turtle draws a branch, brackets back to the fork, and starts the next branch from the same point.

Why do L-system trees look more like real plants than hand-drawn fractals?

Aristid Lindenmayer originally designed L-systems in 1968 to model how real algae and plant cells actually divide and grow, not to make pretty pictures. Parametric and stochastic extensions let branch length taper with each generation and let angles vary randomly within a range, which mimics the biological variability of real growth far better than a rigid, exactly self-similar fractal.

Why does the string length explode so fast?

Because every symbol in the string is rewritten in parallel, every generation, according to its production rule. If a rule replaces one symbol with k symbols, the string length roughly multiplies by k each generation, so length grows exponentially in the number of generations even though the rule itself is just a few characters long.

Try it live

Everything above runs in your browser — open L-System Fractals and change the parameters while it is running. Nothing is installed, nothing is uploaded, the whole model lives in one tab.

▶ Open L-System Fractals simulation

What did you find?

Add reproduction steps (optional)