Next generation MIDI for the web


To install the latest version of mpe.js:

npm install --save mpe

Or using yarn:

yarn add mpe

To use without a package manager:

<script src='//'></script>

Quick start

Once installed from npm, mpe.js can be used in any of these ways.

  • ES2015 module (recommended)
    import mpeInstrument from 'mpe';
  • Script tag
    <script src='path/to/mpe/lib/mpe.min.js'></script>
    Note: Using lib/mpe.js or lib/mpe.min.js via a script tag will assign module contents to window.mpe.


mpeInstrument (options) ./src/mpeInstrument/index.js

Creates a new instrument instance for processing MPE data

options: Object
Name Description
options.log (default false) Log instrument state to the console on change
options.normalize (default false) For all notes, remap timbre , noteOnVelocity , noteOffVelocity and pressure between 0 and 1, remap pitchBend between -1 and 1
options.pitch (default false) Adds a pitch property to all notes: uses scientific notation eg. C4 when true or 'scientific' , uses Helmholtz notation eg. c' when set to 'helmholtz'
options.pitchBendRange (default 48) Converts pitchBend to the range specified, overriding normalize if both are set
Object Instance representing an MPE compatible instrument
import mpeInstrument from 'mpe';

// Define `instrument` as an instance of `mpeInstrument`
const instrument = mpeInstrument();

// Request MIDI device access from the Web MIDI API
navigator.requestMIDIAccess().then(access => {
  // Iterate over the list of inputs returned
  access.inputs.forEach(midiInput => {
    // Send 'midimessage' events to the mpe.js `instrument` instance
      (event) => instrument.processMidiMessage(
Instance Members


What is MPE?

MPE stands for “MIDI Polyphonic Expression” and is an extension of MIDI 1.0.

How does MPE differ from MIDI 1.0?

MPE allows individual notes to have independent pitch bend values whereas MIDI 1.0 only allows these to be set globally for all voices at once.

Instruments following the MPE proposed specification assign conventional note on/off messages into “note channels”.

What MPE controllers and MPE compatible software is currently available?

ROLI’s Seaboard and BLOCKS controllers, the Haken Continuum and the Linnstrument are all MPE compatible.

The MPE working group is supported by ROLI, Apple, Bitwig, Moog, Haken and Roger Linn Design. MPE is currently implemented in Logic X, Bitwig Studio and Cubase, as well as ROLI’s Equator and NOISE software synths.

How does mpe.js help in building an MPE compatible web app?

An mpe.js mpeInstrument instance accepts MPE messages as input and returns a standardized representation of the current touch state described. MPE messages are reduced to a sorted array of “active note” objects with named properties that update in response to new input messages.

Without mpe.js, a developer would need to process individual MPE messages, apply bitwise operations to derive the message's meaning (with reference to the MPE proposed specification) and then apply the derived instruction to a manually collected representation of the instrument state.

What's the difference between an MPE message and a standard MIDI message?

None. For the purpose of backwards compatibility, MPE only changes the convention by which messages are interpretted rather than MIDI communication protocol itself. An MPE message is a 1–3 byte message that can be sent and received in all the same ways.

Can I use mpe.js with MIDI 1.0?

Yes. Whilst certain parameters won't be relevant – timbre, for example – mpe.js's touch state representation is fully backwards compatible with MIDI 1.0 instruments.

Do I have to use this with the Web MIDI API?

No. mpe.js can be used to simplify reading recorded MPE data in the browser without depending on Web MIDI API for live input. It can also be used in node.js, either for offline usage, or processing live input via I/O libraries such as node-midi.

Why would I build a synth/visualisation/music web application using browsers or node.js?

We've found JavaScript tools to be a convenient medium for prototyping and see potential beyond that for the future. Whilst there is cause for excitement in the area, your mileage may vary.

Are there tools to use MPE in other programming languages?

Yes! A C++ implementation is included in JUCE.