5 min read

Stop using p5.js

I'm coming home from A MAZE and feeling alive and connected to the world. Surprisingly! So let's use this energy to write a little blog post.

This is one I've been meaning to write for a while. It's one where I'm a hater! What am I hating on? (you already know, it's in the title).

I think people should stop using p5.js. Now, whenever you tell people they should stop doing something, it's worth (unless you're purely enjoying being a hater) applying Chesterton's Fence, and asking why people use it now. So here's my understanding of what p5.js is and why they use it:

p5.js is a port of the Processing creative coding environment to Javascript. Processing was written in Java and gives you a nice framework for doing quick "sketches" of code, making procedural visuals, maybe some simple animation, a little interactivity, a fun little exploration of code. I have no beef with Processing. It's especially great to use if you're teaching students - the small scope is good for projects, the visual approach makes the stuff you're making immediate and exciting... maybe you're teaching them coding in general, or maybe you're getting them used to making little artworks in code. It gets you going quickly!

So then when it become clear that the energy was shifting from programs you run within your operating system to programs you run within a browser, Processing was seemed like it was getting increasingly irrelevant. So they made p5.js, and all the professors who were teaching Processing shifted to p5.js instead. It's a pretty close match, just in a new programming language. There's great resources out there if you wanna teach it, it's well supported. I get why teachers teach it!

But! I did not learn how to do creative coding by being taught p5.js, or indeed Processing,. I learned it by just... messing around in the browser. And the thing about the browser/JS ecosystem is... it's already great for creative coding. The canvas API works great. You have all these native controls ready to hand. You have capable APIs for making sounds, for doing animation, for doing pretty much anything you want. And you don't need to include any libraries - you can just open up a text document, type some HTML, embed some JS, refer to nothing outside that file, and have a working sketch. And it'll run on any modern browser.

(A moment to acknowledge here that of course in this whole rant I'm defending the thing I find familiar over the thing that's new to me. The bias is acknowledged! But I don't think that's the only thing happening here)

A while back, I took part in advent.js, a little advent calendar compilation of creative code sketches. The submissions where supposed to be done in p5.js – because they were all going to be connected together into a single thing – and while I knew enough that I could have shimmed out to native code, I decided to give it a go and work natively within p5.js. Because it's good to learn new things, and maybe I was missing out on a nice setup for making generative sketches. And, unsurprisingly... it was miserable. I spent half the time working hard to recreate things that the browser natively supports within the limited framework of p5.js.

A more specific example: I wanted to procedurally colour some stuff. I had been having fun looking at oklch, which is a great way to specify colours if you want to vary the hue but keep the perceptual lightness and value constant. It's built into browsers now, you can put a oklch(0.7 0.2135 34.01) into anything that needs a colour specified. And – which is pretty cool – if the browser supports a larger colour gamut, then you get some extra colours. But p5.js doesn't work that way. It needs colours in it's own formats. I mean I know it says it takes a CSS color string, but it doesn't take a oklch one. There's an open bug for it - "In any case I'm not very opposed to implementing this but my main concern is that this will likely require a complete reengineering of how color works in p5.js that will likely touch a lot of moving parts.". So what I did was to add a new library that could take my oklch strings and turn them into a sRGB hex code, which I could then plug into p5.js for it to do it's own colour conversions back into something that could get rendered.

And this felt kind of emblematic of the way that p5.js goes against the grain of the native platform. A lot of work to recreate something that exists natively, but different in some small ways. A lot of work... and yet this is a task which always needs more.

Now I should say that I don't think the web platform is perfect. The Canvas API is a little crufty and weird, it has some implicit state you need to manage in a way that isn't the most clear. But p5.js has even more implicit state. As a little example, let's look at the arc() function - picked because it's the first one on the reference page:

An arc is a section of an ellipse defined by the x, y, w, and h parameters.

Great! We have position and size. What exactly do those mean? Are we setting the center of the arc or the top left corner? Are we setting the bounding box of the circle the arc is part of? Well, the answer is that it could be any of them. It depends on the latest ellipseMode that was set.

The fifth and sixth parameters, start and stop, set the angles between which to draw the arc.

Okay, great! Is that in radians or degrees?

By default, angles are given in radians, but if angleMode (DEGREES) is set, the function interprets the values in degrees.

Oh, okay. But maybe all this is helpful if it simplifies drawing an arc - better than having to do math to figure out how to draw these lines ourselves. Except, let's look at the MDN docs for the arc() function of the Canvas API:

arc(x, y, radius, startAngle, endAngle, counterclockwise)
The arc() method creates a circular arc centered at (x, y) with a radius of radius. The path starts at startAngle, ends at endAngle, and travels in the direction given by counterclockwise (defaulting to clockwise).

This seems less mysterious to me? Less ways that things can go wrong because of implicit state. Not least because - arc() is a method on a CanvasRenderingContext2D. So if you want to have two canvases, you can specify which one, draw one onto the other, etc.

(p5.js can also do multiple canvases, of course. Guess what? it has a mode for that)

Now I should acknowledge that this is just one small corner of p5.js, and that the two functions are not quite equivalent - the Canvas one adds the arc to a path which can then be stroked or filled later, and the p5.js one draws immediately and choosing the stroke or fill is done ahead of time. The p5.js one can do non-uniform scaling, which using Canvas you'd do with a transform. But, like... just on this small example, we can at least say that p5.js is not clearly superior, and definitely not enough to justify learning it's weird crannies rather than the weird crannies of the thing that every browser does natively.

So: I think people should stop using p5.js. I think it is, in terms of code aesthetics, ugly. Inelegant. I think they do use it because it's what they were taught. And they were taught it because it has momentum in the classroom, and it has nice learning resources. I guess the concrete obstacle in the way of this changing is someone remaking all the nice p5.js teaching materials to instead be about native APIs. So: someone should do that. Maybe the Processing Foundation?

Further reading:
Ben Fry resigning from the Processing Foundation board
one of my a simple creative coding sketches, with a readable single-page view source
MDN Canvas reference

And maybe I'll do a more effortful blog post at some point where I recreate a p5.js example sketch in HTML & JS, to demonstrate that it's not any more complex in practice. Suggestions for a sketch to recreate welcome!