Use when users request: p5.js sketches, creative coding, generative art, interactive visualizations, canvas animations, browser-based visual art, data viz, shader effects, or any p5.js project.
What's inside
Production pipeline for interactive and generative visual art using p5.js. Creates browser-based sketches, generative art, data visualizations, interactive experiences, 3D scenes, audio-reactive visuals, and motion graphics — exported as HTML, PNG, GIF, MP4, or SVG. Covers: 2D/3D rendering, noise and particle systems, flow fields, shaders (GLSL), pixel manipulation, kinetic typography, WebGL scenes, audio analysis, mouse/keyboard interaction, and headless high-res export.
Creative Standard
This is visual art rendered in the browser. The canvas is the medium; the algorithm is the brush.
Before writing a single line of code, articulate the creative concept. What does this piece communicate? What makes the viewer stop scrolling? What separates this from a code tutorial example? The user's prompt is a starting point — interpret it with creative ambition.
First-render excellence is non-negotiable. The output must be visually striking on first load. If it looks like a p5.js tutorial exercise, a default configuration, or "AI-generated creative coding," it is wrong. Rethink before shipping.
Go beyond the reference vocabulary. The noise functions, particle systems, color palettes, and shader effects in the references are a starting vocabulary. For every project, combine, layer, and invent. The catalog is a palette of paints — you write the painting.
Be proactively creative. If the user asks for "a particle system," deliver a particle system with emergent flocking behavior, trailing ghost echoes, palette-shifted depth fog, and a background noise field that breathes. Include at least one visual detail the user didn't ask for but will appreciate.
Dense, layered, considered. Every frame should reward viewing. Never flat white backgrounds. Always compositional hierarchy. Always intentional color. Always micro-detail that only appears on close inspection.
Cohesive aesthetic over feature count. All elements must serve a unified visual language — shared color temperature, consistent stroke weight vocabulary, harmonious motion speeds. A sketch with ten unrelated effects is worse than one with three that belong together.
Modes
Mode
Input
Output
Reference
Generative art
Seed / parameters
Procedural visual composition (still or animated)
references/visual-effects.md
Data visualization
Dataset / API
Interactive charts, graphs, custom data displays
references/interaction.md
Interactive experience
None (user drives)
Mouse/keyboard/touch-driven sketch
references/interaction.md
Animation / motion graphics
Timeline / storyboard
Timed sequences, kinetic typography, transitions
references/animation.md
3D scene
Concept description
WebGL geometry, lighting, camera, materials
references/webgl-and-3d.md
Image processing
Image file(s)
Pixel manipulation, filters, mosaic, pointillism
references/visual-effects.md § Pixel Manipulation
Audio-reactive
Audio file / mic
Sound-driven generative visuals
references/interaction.md § Audio Input
Stack
Single self-contained HTML file per project. No build step required.
Thresholds — when does behavior change? (controls drama)
Ratios — proportions, balance between forces (controls harmony)
Bad parameters are generic controls unrelated to the algorithm:
"color1", "color2", "size" — meaningless without context
Toggle switches for unrelated effects
Parameters that only change cosmetics, not behavior
Every parameter should change how the algorithm thinks, not just how it looks. A "turbulence" parameter that changes noise octaves is good. A "particle size" slider that only changes ellipse() radius is shallow.
Workflow
Step 1: Creative Vision
Before any code, articulate:
Mood / atmosphere: What should the viewer feel? Contemplative? Energized? Unsettled? Playful?
Visual story: What happens over time (or on interaction)? Build? Decay? Transform? Oscillate?
Color world: Warm/cool? Monochrome? Complementary? What's the dominant hue? The accent?
Interaction model — passive (no input), mouse-driven, keyboard-driven, audio-reactive, scroll-driven
Viewer UI — for interactive generative art, start from templates/viewer.html which provides seed navigation, parameter sliders, and download. For simple sketches or video export, use bare HTML
Step 3: Code the Sketch
For interactive generative art (seed exploration, parameter tuning): start from templates/viewer.html. Read the template first, keep the fixed sections (seed nav, actions), replace the algorithm and parameter controls. This gives the user seed prev/next/random/jump, parameter sliders with live update, and PNG download — all wired up.
For animations, video export, or simple sketches: use bare HTML:
Does it match the vision? Compare output to the creative concept. If it looks generic, go back to Step 1
Resolution check: Is it sharp at the target display size? No aliasing artifacts?
Performance check: Does it hold 60fps in browser? (30fps minimum for animations)
Color check: Do the colors work together? Test on both light and dark monitors
Edge cases: What happens at canvas edges? On resize? After running for 10 minutes?
Critical Implementation Notes
Performance — Disable FES First
The Friendly Error System (FES) adds up to 10x overhead. Disable it in every production sketch:
p5.disableFriendlyErrors = true; // BEFORE setup()functionsetup() {
pixelDensity(1); // prevent 2x-4x overdraw on retinacreateCanvas(1920, 1080);
}
In hot loops (particles, pixel ops), use Math.* instead of p5 wrappers — measurably faster:
// In draw() or update() hot paths:let a = Math.sin(t); // not sin(t)let r = Math.sqrt(dx*dx+dy*dy); // not dist() — or better: skip sqrt, compare magSqlet v = Math.random(); // not random() — when seed not neededlet m = Math.min(a, b); // not min(a, b)
Never console.log() inside draw(). Never manipulate DOM in draw(). See references/troubleshooting.md § Performance.
Seeded Randomness — Always
Every generative sketch must be reproducible. Same seed, same output.
functionsetup() {
randomSeed(CONFIG.seed);
noiseSeed(CONFIG.seed);
// All random() and noise() calls now deterministic
}
Never use Math.random() for generative content — only for performance-critical non-visual code. Always random() for visual elements. If you need a random seed: CONFIG.seed = floor(random(99999)).
Generative Art Platform Support (fxhash / Art Blocks)
For generative art platforms, replace p5's PRNG with the platform's deterministic random:
// fxhash conventionconstSEED = $fx.hash; // unique per mintconst rng = $fx.rand; // deterministic PRNG
$fx.features({ palette: 'warm', complexity: 'high' });
// In setup():randomSeed(SEED); // for p5's noise()noiseSeed(SEED);
// Replace random() with rng() for platform determinismlet x = rng() * width; // instead of random(width)
See references/export-pipeline.md § Platform Export.
Color Mode — Use HSB
HSB (Hue, Saturation, Brightness) is dramatically easier to work with than RGB for generative art:
Never hardcode raw RGB values. Define a palette object, derive variations procedurally. See references/color-systems.md.
Noise — Multi-Octave, Not Raw
Raw noise(x, y) looks like smooth blobs. Layer octaves for natural texture:
functionfbm(x, y, octaves = 4) {
let val = 0, amp = 1, freq = 1, sum = 0;
for (let i = 0; i < octaves; i++) {
val += noise(x * freq, y * freq) * amp;
sum += amp;
amp *= 0.5;
freq *= 2;
}
return val / sum;
}
For flowing organic forms, use domain warping: feed noise output back as noise input coordinates. See references/visual-effects.md.
createGraphics() for Layers — Not Optional
Flat single-pass rendering looks flat. Use offscreen buffers for composition:
For headless rendering via Puppeteer, the sketch must use noLoop() in setup. Without it, p5's draw loop runs freely while screenshots are slow — the sketch races ahead and you get skipped/duplicate frames.
The bundled scripts/export-frames.js detects _p5Ready and calls redraw() once per capture for exact 1:1 frame correspondence. See references/export-pipeline.md § Deterministic Capture.
For multi-scene videos, use the per-clip architecture: one HTML per scene, render independently, stitch with ffmpeg -f concat. See references/export-pipeline.md § Per-Clip Architecture.
Agent Workflow
When building p5.js sketches:
Write the HTML file — single self-contained file, all code inline
Open in browser — open sketch.html (macOS) or xdg-open sketch.html (Linux)
Local assets (fonts, images) require a server: python3 -m http.server 8080 in the project directory, then open http://localhost:8080/sketch.html
Export PNG/GIF — add keyPressed() shortcuts as shown above, tell the user which key to press
Headless export — node scripts/export-frames.js sketch.html --frames 300 for automated frame capture (sketch must use noLoop() + _p5Ready)
Performance profiling, per-pixel budgets, common mistakes, browser compatibility, WebGL debugging, font loading issues, pixel density traps, memory leaks, CORS
templates/viewer.html
Interactive viewer template: seed navigation (prev/next/random/jump), parameter sliders, download PNG, responsive canvas. Start from this for explorable generative art
Creative Divergence (use only when user requests experimental/creative/unique output)
If the user asks for creative, experimental, surprising, or unconventional output, select the strategy that best fits and reason through its steps BEFORE generating code.
Conceptual Blending — when the user names two things to combine or wants hybrid aesthetics
SCAMPER — when the user wants a twist on a known generative art pattern
Distance Association — when the user gives a single concept and wants exploration ("make something about time")
Conceptual Blending
Name two distinct visual systems (e.g., particle physics + handwriting)