JavaScript library for MIDI communication that simplifies sending and receiving MIDI messages between browsers/Node.js and MIDI instruments
npx @tessl/cli install tessl/npm-webmidi@3.1.0WebMidi.js is a comprehensive JavaScript library that simplifies working with the Web MIDI API. It provides an easy-to-use interface for sending and receiving MIDI messages between browsers/Node.js and MIDI instruments, with support for both virtual and hardware devices.
npm install webmidinpm install jzz (for Node.js MIDI support)import { WebMidi, Input, Output, Note } from "webmidi";For CommonJS:
const { WebMidi, Input, Output, Note } = require("webmidi");All available exports:
import {
WebMidi,
Enumerations,
Forwarder,
Input,
InputChannel,
Message,
Note,
Output,
OutputChannel,
Utilities
} from "webmidi";import { WebMidi } from "webmidi";
// Enable WebMidi.js (required before using any functionality)
WebMidi.enable()
.then(() => {
console.log("WebMidi enabled!");
// List available devices
console.log("Inputs:", WebMidi.inputs);
console.log("Outputs:", WebMidi.outputs);
// Get first available output and play a note
const output = WebMidi.outputs[0];
if (output) {
output.playNote("C4", 1, { duration: 1000 });
}
// Listen for input messages
const input = WebMidi.inputs[0];
if (input) {
input.addListener("noteon", (e) => {
console.log("Note played:", e.note.name + e.note.octave);
});
}
})
.catch(err => console.log("WebMidi could not be enabled:", err));WebMidi.js is built around several key components:
Central singleton for MIDI access control, device management, and global utilities.
class WebMidi {
static enable(options?: {sysex?: boolean}, legacy?: boolean): Promise<WebMidi>;
static get enabled(): boolean;
static get supported(): boolean;
static get inputs(): Input[];
static get outputs(): Output[];
static getInputById(id: string, options?: {disconnected?: boolean}): Input | false;
static getInputByName(name: string, options?: {disconnected?: boolean}): Input | false;
static getOutputById(id: string, options?: {disconnected?: boolean}): Output | false;
static getOutputByName(name: string, options?: {disconnected?: boolean}): Output | false;
}Comprehensive input handling for receiving and processing MIDI messages from devices.
class Input extends EventEmitter {
readonly channels: InputChannel[];
readonly name: string;
readonly id: string;
readonly connection: string;
readonly state: string;
addListener(event: string, listener: Function, options?: object): Input;
removeListener(event: string, listener: Function, options?: object): Input;
addForwarder(output: Output, options?: object): void;
}
class InputChannel extends EventEmitter {
readonly number: number;
readonly input: Input;
getNoteState(note: string | number): object;
}Complete output functionality for sending MIDI messages to instruments and devices.
class Output extends EventEmitter {
readonly channels: OutputChannel[];
readonly name: string;
readonly id: string;
readonly connection: string;
readonly state: string;
send(message: number[] | Uint8Array, options?: {time?: number}): Output;
sendSysex(identification: number[], data?: number[], options?: object): Output;
clear(): Output;
}
class OutputChannel extends EventEmitter {
readonly number: number;
readonly output: Output;
playNote(note: string | number | Note[], options?: object): OutputChannel;
stopNote(note: string | number | Note[], options?: object): OutputChannel;
sendControlChange(controller: number | string, value: number, options?: object): OutputChannel;
sendPitchBend(value: number, options?: object): OutputChannel;
sendProgramChange(program: number, options?: object): OutputChannel;
}Musical note representation and conversion utilities for MIDI note processing.
class Note {
constructor(value: string | number | Note, options?: object);
readonly identifier: string;
readonly name: string;
readonly accidental?: string;
readonly octave: number;
readonly number: number;
readonly duration?: number;
readonly attack: number;
readonly release: number;
getOffsetNumber(octaveOffset?: number, semitoneOffset?: number): number;
}MIDI message representation and parsing for understanding received MIDI data.
class Message {
constructor(data: Uint8Array);
readonly rawData: Uint8Array;
readonly data: number[];
readonly statusByte: number;
readonly dataBytes: number[];
readonly isChannelMessage: boolean;
readonly isSystemMessage: boolean;
readonly command: number;
readonly channel?: number;
readonly type: string;
}Static utility methods for MIDI data conversion, note processing, and value transformations.
class Utilities {
static toNoteNumber(identifier: string, octaveOffset?: number): number;
static toNoteIdentifier(number: number, octaveOffset?: number): string;
static from7bitToFloat(value: number): number;
static fromFloatTo7Bit(value: number): number;
static fromMsbLsbToFloat(msb: number, lsb?: number): number;
static fromFloatToMsbLsb(value: number): {msb: number, lsb: number};
static sanitizeChannels(channel: number | string | number[]): number[];
static toTimestamp(time?: number | string): number;
}MIDI specification constants and enumerations for all message types and values.
class Enumerations {
static readonly CHANNEL_MESSAGES: object;
static readonly CHANNEL_MODE_MESSAGES: object;
static readonly CONTROL_CHANGE_MESSAGES: object;
static readonly REGISTERED_PARAMETERS: object;
static readonly SYSTEM_MESSAGES: object;
static readonly CHANNEL_EVENTS: string[];
}Forward MIDI messages between inputs and outputs for routing and processing.
class Forwarder {
constructor(destinations?: Output[], options?: object);
readonly destinations: Output[];
forward(message: Message): void;
}WebMidi.js is ideal for:
jzz dependency for MIDI support