# p5js-render > Render p5.js sketches to MP4, WebM or GIF in headless Chromium. Every frame is drawn once, in order, on a virtual clock with a seeded random generator, so the same sketch always makes the same video. p5js-render is an open-source TypeScript tool (MIT license) with a CLI, a Node API and an HTTP API. It loads a p5.js sketch in headless Chromium through Playwright, seeds Math.random, replaces the clock so millis(), deltaTime and Date follow the frame number, draws every frame in order, encodes frames in a worker pool and streams them into ffmpeg. ## Usage - Install: `pnpm install && pnpm exec playwright install chromium` (needs Node.js 22.18+ and ffmpeg) - Render: `pnpm render ./sketch.js -o sketch.mp4 --duration 4 --fps 30 --seed 1` - Formats: the output extension picks .mp4 (H.264), .webm (VP9) or .gif - Debug HUD: `--debug` burns in frame number, time, draw cost and seed - Seamless loops: animate from `window.p5Render.progress` (0 up to 1) ## Docs - [README](https://github.com/jamiew/p5js-render#readme): full CLI options, sketch guidance, library and HTTP API - [Examples](https://github.com/jamiew/p5js-render/tree/main/examples): the sketches shown on the demo site - [Demo site](https://jamiew.github.io/p5js-render/): videos, debug views and scrubbable film strips ## Example renders - [Cube Wave](https://jamiew.github.io/p5js-render/media/cube-wave.mp4): A field of columns rises and falls in a wave spreading from the center. WebGL with an isometric camera, and faces colored by hand instead of lit. After Dave Whyte (Bees & Bombs), 'cube wave'. Source: https://github.com/jamiew/p5js-render/blob/main/examples/cube-wave.js - [Pulsar Ridges](https://jamiew.github.io/p5js-render/media/pulsar-ridges.mp4): Seventy-two ridgelines, each hiding the ones behind it. Combs of subpulses drift through the peaks the way the pulsar CP 1919 really does. After Peter Saville's Unknown Pleasures cover, from Harold Craft's plot of pulsar CP 1919. Source: https://github.com/jamiew/p5js-render/blob/main/examples/pulsar-ridges.js - [Clifford Bloom](https://jamiew.github.io/p5js-render/media/clifford-bloom.mp4): A million points of a Clifford attractor, binned into a density map each frame and tone-mapped from navy to warm white, while its parameters travel a closed loop. After Clifford Pickover and the fractal flame renders of Scott Draves. Source: https://github.com/jamiew/p5js-render/blob/main/examples/clifford-bloom.js - [Flow Fibers](https://jamiew.github.io/p5js-render/media/flow-fibers.mp4): Hundreds of fibers, from bold ribbons to hairlines, grow along a noise flow field. Paths are planned against a collision grid, so strands bundle side by side and never pile up. After Tyler Hobbs (Fidenza) and the flow-field tradition. Source: https://github.com/jamiew/p5js-render/blob/main/examples/flow-fibers.js - [Truchet Weave](https://jamiew.github.io/p5js-render/media/truchet-weave.mp4): A wave sweeps across a grid of Truchet tiles. Each tile makes an eased quarter-turn, so the ribbons break apart and rejoin into a new maze. After Cyril Stanley Smith's Truchet tiles, with palettes after Vera Molnar and Kjetil Golid. Source: https://github.com/jamiew/p5js-render/blob/main/examples/truchet-weave.js - [Reaction Diffusion](https://jamiew.github.io/p5js-render/media/reaction-diffusion.mp4): One seed grows into a coral maze that fills the frame. New growth glows coral and cools to cream, so the finished image records how it grew. After Gray-Scott Turing patterns, after Karl Sims' explainer. Source: https://github.com/jamiew/p5js-render/blob/main/examples/reaction-diffusion.js - [Dot Lattice](https://jamiew.github.io/p5js-render/media/dot-lattice.mp4): A hexagonal lattice swings along its radii. Overlapping dots add up into bright rings, and ten sub-frame samples blur each dot into a streak. After Etienne Jacob and Dave Whyte (Bees & Bombs). Source: https://github.com/jamiew/p5js-render/blob/main/examples/dot-lattice.js - [Schotter Drift](https://jamiew.github.io/p5js-render/media/schotter-drift.mp4): A column of inked squares, calm at the top and rubble at the bottom. A slow wave carries it from order to chaos and back. After Georg Nees, Schotter (1968). Source: https://github.com/jamiew/p5js-render/blob/main/examples/schotter-drift.js - [Moire Orbit](https://jamiew.github.io/p5js-render/media/moire-orbit.mp4): Two sets of fine rings with slightly different spacing circle each other, and their interference makes broad spiral fringes that stream outward. After Bridget Riley's op art and Ryoji Ikeda's precise minimalism. Source: https://github.com/jamiew/p5js-render/blob/main/examples/moire-orbit.js ## FAQ ### How do I render a p5.js sketch to an MP4 video? Install p5js-render with pnpm, run pnpm exec playwright install chromium once, then run pnpm render ./sketch.js -o sketch.mp4 --duration 4. The sketch runs in headless Chromium and each frame streams into ffmpeg. ### How do I make a p5.js animation loop seamlessly? Drive every motion from window.p5Render.progress, which runs from 0 up to (not including) 1 across the video. Use whole periods such as sin(TWO_PI * progress), so the frame after the last one matches the first. ### Why do screen recordings of p5.js sketches drop frames or differ between runs? Live recording depends on the wall clock and on Math.random. p5js-render replaces both: millis(), deltaTime and Date follow the frame number, and random() and noise() are seeded, so every render of the same sketch and seed is identical. ### Can I export a p5.js sketch as a GIF or WebM? Yes. The output extension picks the format: .mp4 for H.264, .webm for VP9 and .gif for a looping GIF with an optimized palette. ### Does it support WebGL, p5.js 2.x and async setup? Yes. It runs the installed p5.js 2.x by default, awaits async setup(), supports instance mode and WEBGL canvases, and can load any p5 version with --p5-version. ### How is p5js-render different from p5.capture or CCapture? p5.capture and CCapture record inside your browser tab. p5js-render runs from the command line, a Node API or an HTTP server, so it suits batch renders, CI and servers, and it keeps stateful sketches exact by drawing every frame in order.