A couple of days ago, P5.js was released into the wild. It’s a JavaScript library for visual programming that follows the Processing doctrine.

As per this post:

Processing is an environment/programming language that is meant to make visual, interactive applications extremely easy to write. It can be used for everything from teaching children how to code to visualizing scientific data.

It’s the language that’s partially behind wizardry like this:

and this:

and, of course, everything you can find here.

But, if we had processing.js before, what’s P5.js?

What is P5.js?

P5.js is a JavaScript library aiming

to make coding accessible for artists, designers, educators, and beginners, and reinterprets this for today’s web

So, it sounds like Processing itself. But what is it really?

Ease up, confused reader, we’ll get to it! First, watch their amazingly enthusiastic introduction here, then come back.

Did it click? Get it now? No? Ok. Let’s break it down.

Differences between Processing.js and P5.js

TL;DR: P5 is a direct JS port of the Processing language. Processing.js is a converter which interprets pure Processing code into JS on the fly. The latter requires you to learn Processing, but not JS, and vice versa.


Live compilation vs Language Translation: Processing.js is a library which takes raw Processing code (which is similar to Java, with types and all) and converts it to JavaScript on the fly. The examples you see running in your browser on the Processing.js website are, in fact, pure Processing code translated live into JS. This conversion is, for example, similar to what you get when you use Dart2js to run Dart code in browsers without a built-in Dart VM. On the other hand, P5 is a full conversion of Processing into JS code – all the functions will eventually be translated, and you’ll be writing in JavaScript.

In Processing.js, you need to define a canvas area with a data source which leads to a PDE file (a file with Processing source code). There are alternative approaches, too, but in a nutshell, that’s it. In P5, you write JS code directly, and it gets executed like any other JS file you include on your website.

Extending: Another difference is that P5 can be extended with addon libraries. For example, the p5.dom.js library addition adds the option of creating and manipulating HTML elements with P5, adding sliders, buttons, form elements and much more to your sketches – much like the demonstrators did in the Hello video we linked to in the previous section.

Note that of the two, only P5 is officially supported by the Processing Foundation and there’s even a transition manual for Processing users here.

Demos

Let’s see a demo comparison to get the full gist of it. I’ve made a Github repository containing the same demo written with each approach.

git clone https://github.com/Swader/processing

In the processing folder, you have two subfolders: processing and p5. Each will contain demo1 and demo2 subdirectories, which contain an index.html file. This is what you can run in your browser and test. The first sample is from the P5 website – a continually drawn ellipse which turns black when the mouse is clicked.

Note that Processing.js loads the pde file with an Ajax request (via XHR), so you will get a cross-origin error if you try to open it in your browser by just running index.html. To get it to run properly, you should probably set up a virtual server through which to access the samples. That’s best done with an instance of Homestead Improved in a Vagrant box – you’ll be up and running in five minutes flat.

P5.js

In this case, we need the sketch.js file which contains our sketch code, and the index.html file in which it runs. The sketch.js code is as follows:

function setup() {
  createCanvas(640, 480);
}

function draw() {
  if (mouseIsPressed) {
    fill(0);
  } else {
    fill(255);
  }
  ellipse(mouseX, mouseY, 80, 80);
}

The index.html file contains only this:

<head>
  <script language="javascript" src="../p5.js"></script>
  <!-- uncomment lines below to include extra p5 libraries -->
    <!--<script language="javascript" src="../addons/p5.dom.js"></script>-->
  <!--<script language="javascript" src="../addons/p5.sound.js"></script>-->
  <script language="javascript" src="sketch.js"></script>
</head>

<body>
</body>

Processing.js

For this example, we need a pde file with Processing code. In our case, that’s sketch.pde with the following P5-translated code:

void setup() {
  size(640, 480);
}

void draw() {
  if (mousePressed) {
    fill(0);
  } else {
    fill(255);
  }
  ellipse(mouseX, mouseY, 80, 80);
}

Then, we have our index.html file:

<head>
  <script language="javascript" src="../processing.min.js"></script>
</head>

<body>
    <canvas data-processing-sources="sketch.pde"></canvas>
</body>

Analysis

At first glance, there is no discernible difference. Both samples run at approximately the same speed, perform well, and have similar syntax. However, if you’re using Google Chrome, and go to chrome://flags, then activate the frame rate counter (see the image below), you’ll notice that drawing in the Processing.js canvas maintains a steady frame rate of around 58 to 60, while P5 goes as low as 50 when drawing, and back up to 60 when idle. Another interesting fact is that Processing uses hardware acceleration all the time, even when your cursor is outside the canvas area. P5, on the other hand, pauses the rendering if no changes to the canvas are pending (your cursor is outside the drawing area), hence lightening the load while not drawing.

Demos 2

Let’s do another demo now – a simple particle effect. This particle emitter will spawn gravitationally sensitive particles in random directions, and we’ll take another look at the frame rate. The example we’ll be using (and translating to P5) is this.

Processing.js

The code for sketch.pde is the one from the example linked above:

ParticleSystem ps;

void setup() {
  size(640,360);
  ps = new ParticleSystem(new PVector(width/2,50));
}

void draw() {
  background(0);
  ps.addParticle();
  ps.run();
}

// A simple Particle class

class Particle {
  PVector location;
  PVector velocity;
  PVector acceleration;
  float lifespan;

  Particle(PVector l) {
    acceleration = new PVector(0,0.05);
    velocity = new PVector(random(-1,1),random(-2,0));
    location = l.get();
    lifespan = 255.0;
  }

  void run() {
    update();
    display();
  }

  // Method to update location
  void update() {
    velocity.add(acceleration);
    location.add(velocity);
    lifespan -= 1.0;
  }

  // Method to display
  void display() {
    stroke(255,lifespan);
    fill(255,lifespan);
    ellipse(location.x,location.y,8,8);
  }

  // Is the particle still useful?
  boolean isDead() {
    if (lifespan < 0.0) {
      return true;
    } else {
      return false;
    }
  }
}

// A class to describe a group of Particles
// An ArrayList is used to manage the list of Particles 

class ParticleSystem {
  ArrayList<Particle> particles;
  PVector origin;

  ParticleSystem(PVector location) {
    origin = location.get();
    particles = new ArrayList<Particle>();
  }

  void addParticle() {
    particles.add(new Particle(origin));
  }

  void run() {
    for (int i = particles.size()-1; i >= 0; i--) {
      Particle p = particles.get(i);
      p.run();
      if (p.isDead()) {
        particles.remove(i);
      }
    }
  }
}

P5

The code for P5 when translated from the above is as follows:

var ps;

function setup() {
    createCanvas(640, 360);
    ps = new ParticleSystem(new p5.Vector(width/2, 50));
}

function draw() {
    background(0);
    ps.addParticle();
    ps.run();
}

function Particle(lvector) {
    this.location = lvector.get();
    this.acceleration = new p5.Vector(0,0.05);

    var random1 = Math.random() * ((Math.random() > 0.5) ? -1 : 1);
    var random2 = Math.random() - ((Math.random() > 0.5) ? 1 : 2);

    this.velocity = new p5.Vector(random1, random2);

    this.lifespan = 255.0;
}

Particle.prototype.run = function() {
    this.update();
    this.display();
}

Particle.prototype.update = function() {
    this.velocity.add(this.acceleration);
    this.location.add(this.velocity);
    this.lifespan -= 1.0;
}

Particle.prototype.display = function() {
    stroke(255, this.lifespan);
    fill(255, this.lifespan);
    ellipse(this.location.x, this.location.y, 8, 8);    
}

Particle.prototype.isDead = function() {
    return (this.lifespan < 0);
}

function ParticleSystem(location) {
    this.origin = location.get();
    this.particles = [];
}

ParticleSystem.prototype.addParticle = function() {
    this.particles.push(new Particle(this.origin));
}

ParticleSystem.prototype.run = function() {
    var p;
    for (var i = this.particles.length - 1; i >= 0; i--) {
        p = this.particles[i];
        p.run();
        if (p.isDead()) {
            this.particles.splice(i, 1);
        }
    }
}

Analysis

Once again, we see a slightly better frame rate with Processing.js. P5 maintains it at around 56, while Processing.js looks to be standing ground at 58 or so. In both cases, Processing.js has proven victorious, performance-wise.

Conclusion

P5js is a young and ambitious project that aims to bring visual programming to the masses in a manner more approachable than Processing was until now. While it is currently being forced to be dumbed down somewhat feature-wise, the team is hard at work porting the rest of the Processing language to this JS counterpart.

The advantages of using P5 over Processing.js are:

  • Writing JS code you’re probably already familiar with
  • Officially supported by the Processing Foundation
  • HTML DOM manipulation with the DOM library addon – adding common HTML elements to your P5 sketches and more
  • Lighter on the resources when not drawing

The advantage of using Processing.js:

  • You learn Processing and can use it in environments where it’s faster and more portable to non-web environments
  • Seems to have a steadier frame rate and performs better in both demos we tried

We’ll be keeping an eye on this library and playing around with it regularly. Will you? Let us know if you whip up some interesting examples, we’d love to write about them!

Bruno is a coder from Croatia with Master’s Degrees in Computer Science and English Language and Literature. He’s the editor of SitePoint’s PHP channel and a developer evangelist for Diffbot.com. He avoids legacy code like the plague and when picking projects makes sure they’re as cutting edge as possible. He’s a treadmill desk enthusiast and active (board)gamer who sometimes blogs.

Free Guide:

How to Choose the Right Charting Library for Your Application

How do you make sure that the charting library you choose has everything you need? Sign up to receive this detailed guide from FusionCharts, which explores all the factors you need to consider before making the decision.


  • Jon Howard

    Thanks for the article, since I first saw P5, this was the first question I had.
    With regards processing both systems seem to use canvas to provide rendering support. Is there any plans to add webgl support in the future.

    Also for anyone looking to get into “creative coding” in Javascript I’d advise looking at Pixi.js which provides a seamless layer on top of and supports both canvas and webgl rendering if available. Also Phaser.js which uses Pixi as it’s rendering engine appears to be gathering more and more support as one of the better game / creative coding platforms.-

  • Mike Farrow

    Thanks for a clear concise overview of the differences, I wanted to try processing and P5 is definitely the path I will be following.

    • Bruno Škvorc

      Cheers, glad you liked the post!

  • Bruno Škvorc

    Thank you for the input, that’s valuable information

  • https://www.jamesstone.com James Michael Stone

    Great article and nice break down of the performance differences. Processing can be a confusing beast. It was originally created as a programming language and ide for artists and desginers. It is both an IDE (the one which the Arduino IDE is based on) as well as an API or Library for Java (core.jar in the Processing app). It is sometimes called p5 which adds to the confusion.

    A few years back John Resig did the original port of Processing.js. This allowed you to run many of the Processing .pde sketches (the file format used by Processing) directly in the browser. You can also use it directly as a library for abstraction in JavaScript, much like other libraries such as paper.js. I did a talk a while back doing exactly this at the html5 dev conf. If you are interested, here is a link to some of the code samples and the slides:

    https://github.com/jamesstoneco/canvas-only

    Then recently p5js was released. It is really exciting because they are building it from the ground up to create a Processing-like abstraction for graphics that runs in a more JavaScript friendly way. It is a rethinking of what the ideas from Processing can mean when used directly in the browser in ways that make the most sense for it.

    I think it can encourage people who may not spend the time to learn all of the JavaScript specific ways of interacting with graphics to just go out there and try out some ideas, to experiment and to hopefully create some really cool stuff.

    The other really exciting thing is that there are a ton of resources and amazing books that show you how to do some pretty mind blowing graphics work without having to be an expert to figure out and experiment with.

    Here are just a few that are really worth checking out:

    * Generative Design: Visualize, Program, and Create with Processing by Hartmut Bohnacker, Benedikt Gross, Julia Laub and Claudius Lazzeroni
    * The Nature of Code by Daniel ShiffmanThe Nature of Code by Daniel Shiffman
    * Processing: Creative Coding and Computational Art (Foundation) by Ira Greenberg
    * Visualizing Data: Exploring and Explaining Data with the Processing Environment by Ben Fry

  • Bruno Škvorc

    Thank you for your comment!

  • lukeP

    One of the biggest down falls of P5 is also that you can’t do any 3D stuff currently

  • lokitoki

    how could set the cavas size to the width and height of the browser windows?

Learn JavaScript for free!
Free course: Introduction to JavaScript

Yours when you take up a free 14-day SitePoint Premium trial.