React
A wrapper component that allows you to utilise P5 sketches within React apps.
Install / Use
/learn @P5-wrapper/ReactREADME
![]()
@P5-wrapper/react
A component to integrate P5.js sketches into React apps.
<details><summary>Migrating from version 4?</summary> <p>Breaking changes in v5:
-
Component rename
ReactP5Wrapper→P5Canvas
-
Types
P5WrapperProps→P5CanvasPropsP5WrapperClassName→CanvasContainerClassName
-
Peer dependencies
p5>= 2.0.0react>= 19.0.0react-dom>= 19.0.0
If you are still using version 4, you can find the documentation here.
</p> </details>Installation
To install, use the following command in the format appropriate to your chosen package manager:
[npm|yarn|pnpm] [install|add] p5 @p5-wrapper/react
Peer dependencies
Please note that p5, react and react-dom are peer dependencies. Make sure
they are installed in your project before installing this package.
"peerDependencies": {
"p5": ">= 2.0.0",
"react": ">= 19.0.0",
"react-dom": ">= 19.0.0"
},
TypeScript
If you would like to use Typescript, you should install p5 types in the
development environment:
[npm|yarn|pnpm] [install|add] -D @types/p5
Next.js
If you plan to use this component within a Next.js application, you should instead use our Next.js dynamic implementation instead. To do get started, you can run:
[npm|yarn|pnpm] [install|add] p5 @p5-wrapper/next @p5-wrapper/react
Please continue reading these docs and also look at the Next.js dynamic implementation docs for further supporting information.
Demo & Examples
Live demo
A live demo can be viewed at P5-wrapper.github.io/react.
Examples
The repository contains further examples.
To try them out for yourself fork the repository, be sure you have PNPM installed and then run the following:
git clone git@github.com:<your username>/react.git
cd react
pnpm install
pnpm preview
Then just open http://localhost:3001 in a browser.
Usage
Javascript
import * as React from "react";
import { P5Canvas } from "@p5-wrapper/react";
function sketch(p5) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
export function App() {
return <P5Canvas sketch={sketch} />;
}
TypeScript
TypeScript sketches can be declared in two different ways, below you will find two ways to declare a sketch, both examples do the exact same thing.
In short though, the component requires you to pass a sketch prop. The
sketch prop is simply a function which takes a p5 instance as it's first and
only argument.
Option 1: Declaring a sketch using the P5CanvasInstance type
import * as React from "react";
import { P5Canvas, P5CanvasInstance } from "@p5-wrapper/react";
function sketch(p5: P5CanvasInstance) {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
export function App() {
return <P5Canvas sketch={sketch} />;
}
Option 2: Declaring a sketch using the Sketch type
Using the Sketch type has one nice benefit over using P5CanvasInstance and
that is that the p5 argument passed to the sketch function is auto-typed as a
P5CanvasInstance for you.
Side note:
In general, it comes down to personal preference as to how you declare your sketches and there is nothing wrong with using the
P5CanvasInstancemanually in a regularfunctiondeclaration.
import * as React from "react";
import { P5Canvas, Sketch } from "@p5-wrapper/react";
const sketch: Sketch = p5 => {
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.draw = () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
};
export function App() {
return <P5Canvas sketch={sketch} />;
}
TypeScript Generics
We also support the use of Generics to add type definitions for your props. If
used, the props will be properly typed when the props are passed to the
updateWithProps method.
To utilise generics you can use one of two methods. In both of the examples
below, we create a custom internal type called MySketchProps which is a union
type of SketchProps and a custom type which has a rotation key applied to
it.
Side note:
We could also write the
MySketchPropstype as an interface to do exactly the same thing if that is to your personal preference:interface MySketchProps extends SketchProps { rotation: number; }
This means, in these examples, that when the rotation prop that is provided as
part of the props passed to the updateWithProps function, it will be
correctly typed as a number.
Usage with the P5CanvasInstance type
import { P5Canvas, P5CanvasInstance, SketchProps } from "@p5-wrapper/react";
import React, { useEffect, useState } from "react";
type MySketchProps = SketchProps & {
rotation: number;
};
function sketch(p5: P5CanvasInstance<MySketchProps>) {
let rotation = 0;
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.updateWithProps = props => {
if (props.rotation) {
rotation = (props.rotation * Math.PI) / 180;
}
};
p5.draw = () => {
p5.background(100);
p5.normalMaterial();
p5.noStroke();
p5.push();
p5.rotateY(rotation);
p5.box(100);
p5.pop();
};
}
export function App() {
const [rotation, setRotation] = useState(0);
useEffect(() => {
const interval = setInterval(
() => setRotation(rotation => rotation + 100),
100
);
return () => {
clearInterval(interval);
};
}, []);
return <P5Canvas sketch={sketch} rotation={rotation} />;
}
Usage with the Sketch type
import { P5Canvas, Sketch, SketchProps } from "@p5-wrapper/react";
import React, { useEffect, useState } from "react";
type MySketchProps = SketchProps & {
rotation: number;
};
const sketch: Sketch<MySketchProps> = p5 => {
let rotation = 0;
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.updateWithProps = props => {
if (props.rotation) {
rotation = (props.rotation * Math.PI) / 180;
}
};
p5.draw = () => {
p5.background(100);
p5.normalMaterial();
p5.noStroke();
p5.push();
p5.rotateY(rotation);
p5.box(100);
p5.pop();
};
};
export function App() {
const [rotation, setRotation] = useState(0);
useEffect(() => {
const interval = setInterval(
() => setRotation(rotation => rotation + 100),
100
);
return () => {
clearInterval(interval);
};
}, []);
return <P5Canvas sketch={sketch} rotation={rotation} />;
}
Using abstracted setup and draw functions
import * as React from "react";
import { P5Canvas } from "@p5-wrapper/react";
function setup(p5) {
return () => {
p5.createCanvas(600, 400, p5.WEBGL);
};
}
function draw(p5) {
return () => {
p5.background(250);
p5.normalMaterial();
p5.push();
p5.rotateZ(p5.frameCount * 0.01);
p5.rotateX(p5.frameCount * 0.01);
p5.rotateY(p5.frameCount * 0.01);
p5.plane(100);
p5.pop();
};
}
function sketch(p5) {
p5.setup = setup(p5);
p5.draw = draw(p5);
}
export function App() {
return <P5Canvas sketch={sketch} />;
}
Props
The only required property is the sketch prop. The sketch prop is a function that will be passed a p5 instance to use for rendering your sketches (see the usage section above).
You can pass as many custom props as you want. These will be passed into the updateWithProps method if you have defined it within your sketch.
Reacting to props
In the below example you see the updateWithProps method being used. This is
called when the component initially renders and when the props passed to the
P5Canvas component are changed, if it is set within your sketch. This way we
can render our component and react to component prop changes directly within our
sketches!
import { P5Canvas } from "@p5-wrapper/react";
import React, { useEffect, useState } from "react";
function sketch(p5) {
let rotation = 0;
p5.setup = () => p5.createCanvas(600, 400, p5.WEBGL);
p5.updateWithProps = props => {
if (props.rotation) {
rotation = (props.rotation * Math.PI) / 180;
}
};
p5.draw = () => {
p5.background(100);
p5.normalMaterial();
p5.noStroke();
p5.push();
p5.rotateY(rotation);
p5.box(100);
p5.pop();
};
}
export function App() {
const [rotation, setRotation] = useState(0);
useEffect(() => {
const interval = setInterval(
() => setRotation(rotation => rotation + 100),
100
);
return () => {
clearInterval(interval);
};
}, []);
return <P5Canvas sketch={sketch} rotation={rotation} />;
}
Children
To render a component on top of the sketch, you can add it as a child of the `P
