Setting up Pintura Image Editor with React

For a quick start use the React example project as a guideline.

It includes a normal, modal, and overlay editor example, as well as an example showing how to integrate FilePond with Pintura.

Installing the modules

Using test version

Test versions of the pintura and react-pintura modules are available on NPM.

npm install --save @pqina/react-pintura @pqina/pintura

Using private npm

The pintura module is available on the pqina private npm.

In our project root directory we create a file called .npmrc and copy the snippet below to the file. Then we replace PQINA_NPM_KEY with our private npm key as displayed on the pqina customer portal.


Now we can install the needed modules like shown below.

npm install --save @pqina/react-pintura @pqina/pintura

Using local modules

Instead of installing from the private npm we can create a local_modules folder inside our project root directory. We then copy paste the pintura files from the product package, the react-pintura package is available on npm.

We can now install the modules like shown below.

npm install --save @pqina/react-pintura ./local_modules/pintura

Default implementation example

In the default example below we'll use the getEditorDefaults method to quickly create an image editor.

This creates a "default" editor that has all available plugins loaded and comes preset with all plugin default options and English locale. Each of these settings can be adjusted freely.

// Import the editor styles
import '@pqina/pintura/pintura.css';

// Import the editor default configuration
import { getEditorDefaults } from '@pqina/pintura';

// Import the editor component from `react-pintura`
import { PinturaEditor } from '@pqina/react-pintura';

// get default properties
const editorConfig = getEditorDefaults();

function App() {
    return (
        <div className="App" style={{ height: '600px' }}>

export default App;

Events and properties

To handle events we can use camelcase props. This means that to listen for the Pintura Image Editor load event we have to set the onLoad prop.

<PinturaEditor onLoad={handleEvent} />

Properties can be used as we would with the normal JavaScript version of the editor.

<PinturaEditor src="image.jpeg" />


To run editor methods we need to get a ref to the editor component. We can do so using the useRef hook. When the reference is set up we can access the editor instance.

export default function Example() {
    // get a reference to the PinturaEditor component
    const componentRef = useRef(null);

    const handleUndo = () => {
        // get reference to editor instance
        const { editor } = componentRef.current;

        // run history.undo()

    return (
        <div className="App">
            <button onClick={handleUndo}>Undo</button>

            <div style={{ height: '600px' }}>
                <PinturaEditor ref={componentRef} src={'image.jpeg'} />

Advanced implementation example

In this example we'll create a custom editor, using a custom set of plugins, locale, and available options.

While this example is a lot more verbose it does allow us to create a more optimal editor package. The build process will tree-shake unused functionality resulting in a smaller build target.

// Import the editor styles
import '@pqina/pintura/pintura.css';

// Import the editor functionality
import {
    // Import the default image reader and writer

    // The method used to register the plugins

    // The plugins we want to use

    // The user interface and plugin locale objects

    // Because we use the annotate plugin we also need
    // to import the markup editor locale and the shape preprocessor

    // Import the default configuration for the markup editor and finetune plugins
} from '@pqina/pintura';

// Import the editor component from `react-pintura`
import { PinturaEditor } from '@pqina/react-pintura';

// This registers the plugins with Pintura Image Editor
setPlugins(plugin_crop, plugin_finetune, plugin_annotate);

// Create our editor configuration
const editorConfig = {
    // This will read the image data (required)
    imageReader: createDefaultImageReader(),

    // This will write the output image
    imageWriter: createDefaultImageWriter(),

    // The markup editor default options, tools, shape style controls

    // The finetune util controls

    // This handles complex shapes like arrows / frames
    shapePreprocessor: createDefaultShapePreprocessor(),

    // This will set a square crop aspect ratio
    imageCropAspectRatio: 1,

    // The icons and labels to use in the user interface (required)
    locale: {

function App() {
    return (
        <div className="App" style={{ height: '600px' }}>

export default App;

Next steps

With the editor set up, we can continue to configure the editor to our liking by adjusting the available options exposed by the editor API