Can't access p5.Vector methods in typescript, like random2D() and sub()

Hello, I’m new to p5.js and I’m trying to convert what I learned in a tutorial from the Coding Train into a NextJS app with React and Typescript.

I have this Vehicle class but when I try to use any Vector methods I get that Vector is not found:

import * as p5 from "p5";

export default class Vehicle {
  pos: p5.Vector;
  target: p5.Vector;
  vel: p5.Vector;
  acc: p5.Vector;
  r: number;
  maxspeed: number;
  maxforce: number;

  constructor(p5: p5, x: number, y: number) {
    this.pos = p5.createVector(p5.random(p5.width), p5.random(p5.height)); = p5.Vector.random2D();
    this.vel = p5.createVector(10,20);
    this.acc = p5.createVector();
    this.r = 15; //radius
    this.maxspeed = 5;
    this.maxforce = 0.1;

   behaviors(p5: p5) {
    let arrive = this.arrive(p5,;
   applyForce(force) {

  seek(p5:p5, target) {
    let desired = p5.Vector.sub(target, this.pos);
    let steer = p5.Vector.sub(desired, this.vel);
    return steer;

  arrive(p5: p5, target: p5.Vector) {
    let desired = p5.Vector.sub(target, this.pos);
    let distance = desired.mag();
    let speed = this.maxspeed;
    if (distance < 100) {
      speed =, 0, 100, 0, this.maxspeed);
    let steer = p5.Vector.sub(desired, this.vel);
    return steer;

  update() {

  show(p5: p5) {
    p5.point(this.pos.x, this.pos.y);

according to my package.json I’m using : “@types/p5”: “^1.4.2”, and “react-p5”: “^1.3.30”, as a wrapper. any idea of how to make this work?

The statement import * as p5 from "p5"; makes p5 available as a datatype, but not as the actual p5 constructor.

That is, you can only use p5 to describe things like this after a colon:

  • constructor(p5: p5, x: number, y: number) {
  • behaviors(p5: p5) {
  • pos: p5.Vector;

And if you attempt to access it like this:

  • p5.Vector.random2D();
  • p5.Vector.sub(target, this.pos);
  • new p5(sketch);

It implies that p5 comes straight from the import statement.

However that’s not true, b/c p5 is already available in the global context right after it’s fully loaded within an HTML file:
<script defer src=></script>

Unfortunately, for unknown reasons, the package “@types/p5” fails to tell that to the TypeScript compiler.

So from TypeScript’s PoV, library “p5.js” is a module that must be imported rather than a JS regular library which makes itself globally available as property p5.

Luck for you I used to have those same errors and I’ve been forced to code a solution for it already.

It’s a “.d.ts” file which we don’t have to import it, but merely use the triple-slash directive syntax instead:
/// <reference path="../typings/p5-global.d.ts" />

“p5-global.d.ts” describes another p5 constructor that’s exclusively accessed via the window object:

  • window.p5.Vector.random2D();
  • window.p5.Vector.sub(target, this.pos);
  • new window.p5(sketch);

Therefore we can normally continue using p5 as a datatype.

And then switch to window.p5 only when we need to access the real p5 namespace.

I’ve converted & refactored the original “059_Steering_Text_Paths” to TS as an ES6 module instance mode sketch:

You can watch it running online by clicking on this link.

And also download the whole project from here:


Thank you, sir! You saved me. I also took some ideas from your implementation of the Vehicle class, but others didn’t work, I wonder if it’s because I’m in React.

Muito obrigado :slight_smile:

1 Like