petal
a language for creative coding

petal
code you reshape
while it runs.

Petal is a dataflow language built for live editing. Write a sketch, watch it draw to a canvas in real time, and rewrite it mid-flight — your state keeps running.

flow_field.ptl
compiling petal…
code → canvas

write it, run it, click it.

The same Petal source on the left is compiled to WASM and running on the right. It’s a real program — physics, persistent state, mouse input. Click the canvas to fling in more balls.

bouncing_balls.ptl
1// Bouncing Balls — click to add more balls.
2// Demonstrates state, frame timing, mouse input, and the drawing API.
3 
4state balls = []
5 
6let sw = float(screen_width())
7let sh = float(screen_height())
8let delta = dt()
9 
10// Seed with a few balls on first frame
11if len(balls) == 0 then
12 for i in range(0, 12) do
13 let f = float(i)
14 push(balls, {
15 x: 50.0 + f * 60.0,
16 y: 80.0 + f * 20.0,
17 vx: 80.0 + f * 15.0,
18 vy: 40.0 - f * 8.0,
19 r: 12.0 + f * 1.5,
20 cr: 80 + (i * 23) % 175,
21 cg: 120 + (i * 47) % 135,
22 cb: 200 - (i * 31) % 150
23 })
24 end
25end
26 
27// Add a ball on click
28if mouse_pressed(1) then
29 let mx = float(mouse_x())
30 let my = float(mouse_y())
31 push(balls, {
32 x: mx, y: my,
33 vx: random(-200.0, 200.0),
34 vy: random(-200.0, 0.0),
35 r: random(8.0, 28.0),
36 cr: int(random(80.0, 255.0)),
37 cg: int(random(80.0, 255.0)),
38 cb: int(random(80.0, 255.0))
39 })
40end
41 
42let gravity = 600.0
43 
44// Physics step
45let new_balls = []
46for b in balls do
47 let nvy = b.vy + gravity * delta
48 let nx = b.x + b.vx * delta
49 let ny = b.y + nvy * delta
50 let nvx = b.vx
51 
52 // Wall collisions
53 let final_vx = nvx
54 let final_x = nx
55 if nx - b.r < 0.0 then
56 final_x = b.r
57 final_vx = -nvx * 0.85
58 end
59 if nx + b.r > sw then
60 final_x = sw - b.r
61 final_vx = -nvx * 0.85
62 end
63 
64 let final_vy = nvy
65 let final_y = ny
66 if ny + b.r > sh then
67 final_y = sh - b.r
68 final_vy = -nvy * 0.85
69 end
70 if ny - b.r < 0.0 then
71 final_y = b.r
72 final_vy = -nvy * 0.85
73 end
74 
75 push(new_balls, {
76 x: final_x, y: final_y,
77 vx: final_vx, vy: final_vy,
78 r: b.r, cr: b.cr, cg: b.cg, cb: b.cb
79 })
80end
81balls = new_balls
82 
83// === Drawing ===
84clear(14, 16, 28)
85 
86for b in balls do
87 // soft outer halo
88 draw_circle(int(b.x), int(b.y), int(b.r + 3.0), b.cr / 4, b.cg / 4, b.cb / 4)
89 draw_circle(int(b.x), int(b.y), int(b.r), b.cr, b.cg, b.cb)
90 draw_circle(int(b.x - b.r * 0.3), int(b.y - b.r * 0.3), int(b.r * 0.35),
91 min(255, b.cr + 60), min(255, b.cg + 60), min(255, b.cb + 60))
92end
93 
94draw_text("Bouncing Balls — click to add", 16, 12, 14, 200, 200, 220)
95draw_text("count: " ++ str(len(balls)), 16, 32, 12, 150, 150, 180)
running · click to add
compiling petal…
why petal

built for the edit-while-it-runs loop.

dataflow graph

Every program is a graph of values flowing into each other. The runtime knows what depends on what — so it only recomputes what changed.

first-class state

Mark a variable as state and it persists across frames and calls — and survives a hot reload. Your simulation keeps running while you edit it.

live editing

A step-based evaluator lets you reshape code while it runs. Change a number, rewrite a function, watch the canvas respond instantly.

compiles to wasm

Petal compiles to WebAssembly and draws straight to a canvas. The whole site runs Petal in your browser — no install required.

live gallery

everything here is actually running.

Generative art, a playable game, a paint tool — each is a single Petal file compiled in your browser. Open any one in the playground and start poking at it.

starfield.ptl
compiling petal…

Starfield

3dgenerative

A 3D star projection with motion trails. Warp speed, ~30 lines.

open starfield
snake.ptl
compiling petal…

Snake

gameinteractive

A complete, playable game in one Petal file. Arrow keys to steer.

open snake
paint.ptl
compiling petal…

Paint

toolinteractive

A little paint program — palette, brush sizes, and a procedurally drawn mandala on first run.

open paint
no install required

open a blank canvas and start typing.

The playground compiles Petal to WASM as you type and runs it live. Nothing to download — just an editor, a canvas, and the edit loop.