Create generative algorithmic art in Jupyter notebooks using p5.js. Use when asked to create generative art, creative coding, algorithmic visuals, or p5.js sketches in a notebook.
This skill creates generative art in Jupyter notebooks using the p5.js kernel for JupyterLite. It follows a two-phase process: developing a computational aesthetic philosophy, then expressing it through code cells.
Understanding how the kernel works is essential for writing correct notebooks.
When you run a code cell, the kernel registers the code (variables, functions, classes) in an internal code registry — it does not render anything visually. The registry uses AST-based deduplication, so later definitions of the same function or variable override earlier ones. This means you can redefine setup() or draw() in a later cell and it will replace the previous version.
%show Renders the SketchThe %show magic is the only way to display a sketch. When executed, it:
setup() then draw() loop)Without %show, nothing is displayed — code cells only register definitions.
After a %show cell has been displayed, re-executing any code cell automatically updates all existing %show displays with the new code. This enables live tweaking of parameters and functions without re-running %show.
The kernel runs p5.js in global mode. All p5.js functions and constants are available as globals — no p5. prefix needed:
createCanvas, background, fill, stroke, noFill, noStroke, circle, rect, ellipse, line, point, triangle, quad, arc, beginShape, vertex, endShapecolor, colorMode, lerpColor, red, green, blue, alpha, hue, saturation, brightnessrandom, noise, map, lerp, constrain, dist, abs, floor, ceil, round, sin, cos, atan2, pow, sqrt, log, exp, min, maxcreateVector, p5.Vector.fromAngle, p5.Vector.random2Dtranslate, rotate, scale, push, pop, applyMatrixPI, TWO_PI, HALF_PI, QUARTER_PI, TAU, CENTER, CORNER, CORNERS, RADIUS, CLOSEwidth, height, mouseX, mouseY, pmouseX, pmouseY, frameCount, deltaTime, windowWidth, windowHeight, innerWidth, innerHeightrandomSeed, noiseSeednoLoop, loop, frameRate, redrawblendMode, ADD, MULTIPLY, SCREEN, OVERLAY, DIFFERENCEThe kernel supports ES module imports from npm (auto-resolved via jsDelivr), GitHub, or direct URLs:
// npm package (default import)
import confetti from 'canvas-confetti';
// Named imports
import { shuffle, debounce } from 'lodash-es';
// Namespace import
import * as d3 from 'd3';
// From GitHub
import something from 'gh/user/repo/file.js';
// Direct URL
import lib from 'https://example.com/lib.js';
Imports are tracked across cells and included when %show generates the sketch.
p5.js event handler functions can be defined in code cells and will be included in the sketch:
mousePressed(), mouseReleased(), mouseMoved(), mouseDragged(), mouseClicked(), doubleClicked(), mouseWheel()keyPressed(), keyReleased(), keyTyped()windowResized()When you need to look up specific p5.js functions, signatures, or behavior, consult the official documentation:
The kernel also provides built-in documentation for p5.js functions via Shift+Tab inspect in the notebook.
Before writing any code, develop a manifesto for a generative aesthetic movement. Write 4-6 paragraphs in a markdown cell covering:
Key principle: "Beauty lives in the process, not the final frame." Each execution with a different seed reveals unique variations of the same algorithmic vision.
Implement the philosophy through notebook cells using the p5.js kernel.
Create a notebook (.ipynb) with the following cell structure:
# [Movement Name]
[4-6 paragraphs of algorithmic philosophy developed in Phase 1]
Define all tunable parameters at the top so they are easy to adjust:
// Seed for reproducibility
let seed = 42;
// Parameters — tunable system properties
let params = {
particleCount: 500,
noiseScale: 0.005,
flowSpeed: 2.0,
trailLength: 50,
colorShift: 0.3,
decayRate: 0.95,
angleOffset: PI / 6,
threshold: 0.4
};
// Palette
let palette = ['#264653', '#2a9d8f', '#e9c46a', '#f4a261', '#e76f51'];
If the algorithm requires helper classes or utility functions, define them in intermediate cells before the main sketch:
class Particle {
constructor(x, y) {
this.pos = createVector(x, y);
this.vel = createVector(0, 0);
// ...
}
update() { /* ... */ }
display() { /* ... */ }
}
Use markdown cells between code sections to explain the algorithmic approach when helpful.
setup() and draw() (Code)The main p5.js sketch with setup() and draw(). All parameters, classes, and helpers must be defined in earlier cells first.
function setup() {
createCanvas(innerWidth, innerHeight);
randomSeed(seed);
noiseSeed(seed);
// ... initialization using params, palette, and helper classes from earlier cells
}
function draw() {
// ... generative algorithm
}
%show (Code)The %show magic is required to render the sketch. Without it, code cells only register definitions — nothing is displayed. This MUST be the last cell.
%show
%show accepts optional width and height arguments (defaults: 100% width, 400px height):
%show 100% 800
Every sketch MUST use seeded randomness for reproducibility:
randomSeed(seed);
noiseSeed(seed);
Changing the seed should produce a distinct but aesthetically coherent variation.
Design parameters around system qualities, not pattern types:
createCanvas(innerWidth, innerHeight) so the sketch fills the %show output iframe — this ensures proper rendering regardless of the display sizebackground() in setup() for static compositions, or with low alpha in draw() for trail effectsnoStroke() with filled shapes, or thin strokes with noFill(), depending on the aestheticblendMode() for layering effects when appropriatecolorMode(HSB, 360, 100, 100, 100) for hue-based generative colornoLoop() for static compositions that render onceChoose approaches that serve the philosophy. Some possibilities:
mouseX/mouseY for the core composition — interactivity is optional and secondary to the algorithmic output%show cell — without it, the sketch will not render