npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@misofm/control-surface

v0.1.2

Published

Typed control-surface drivers and Web MIDI transport for browser-based audio applications.

Readme

@misofm/control-surface

CI npm License

Typed, framework-independent control-surface drivers for browser-based audio applications.

The first driver supports the full-size Behringer X-Touch in Mackie Control mode over Web MIDI. It provides a typed MCU/X-Touch wire codec and owns the browser MIDI lifecycle without imposing a DAW session model, UI framework, or parameter-mapping policy.

[!NOTE] The package is at 0.1.x. The X-Touch API is usable and tested, but the cross-device abstraction will be allowed to emerge as additional hardware drivers are implemented.

Features

  • Typed decoding for faders, fader touch, encoders, encoder presses, channel buttons, banking, transport, and jog input.
  • Feedback encoders for motor faders, encoder rings, LEDs, meters, scribble strips, strip colors, and time/assignment displays.
  • Web MIDI permission, SysEx, discovery, port-open, hot-plug, reconnect, and error handling.
  • Framework-independent connection snapshots and input subscriptions.
  • Dependency-free runtime with injectable MIDI access and port selection for deterministic tests.
  • Separate host/application semantics: the driver never decides what a track, bank, plug-in page, or transport command means.

Hardware support

| Device | Transport | Protocol | Status | | ----------------------------- | --------------------------------------- | -------------- | -------------------------------------- | | Behringer X-Touch, full-size | Web MIDI endpoint identified as X-Touch | Mackie Control | Supported baseline | | X-Touch Extender | — | — | Not yet supported | | X-Touch One, Compact, Mini | — | — | Not supported by this driver | | Other MCU-compatible surfaces | — | Mackie Control | Untested; compatibility is not claimed |

The full-size matcher intentionally rejects Extender and secondary EXT / MIDI 2 endpoints. Explicit selection of generically named MIDI-interface or network-session endpoints is not implemented yet.

Requirements

  • A browser/runtime exposing the Web MIDI API in a secure context.
  • User permission for MIDI access. The default X-Touch connection requests SysEx because scribble strips and strip colors require it.
  • TypeScript projects should include the DOM library for Web MIDI types.
  • A full-size X-Touch configured for Mackie Control (MC) mode.

Call connect() from a user-initiated action such as a button click so the browser can present its permission UI.

Installation

Install the package from npm:

bun add @misofm/control-surface

The package is ESM-only and ships compiled JavaScript plus declarations.

Quick start

import {
  WebMidiXTouchDevice,
  mcuChannelButtonLedMessage,
} from "@misofm/control-surface/xtouch";

const device = new WebMidiXTouchDevice();

const unsubscribeState = device.subscribe(() => {
  const state = device.getSnapshot();
  console.log(state.status, state.deviceName, state.error);
});

const unsubscribeInput = device.subscribeInput((event) => {
  switch (event.type) {
    case "fader":
      console.log(event.fader, event.position);
      break;
    case "transport-button":
      console.log(event.button, event.pressed);
      break;
  }
});

// Invoke from a user gesture.
await device.connect();

device.send(mcuChannelButtonLedMessage("select", 0, true));

unsubscribeInput();
unsubscribeState();
device.disconnect();

The device emits physical events and accepts MIDI feedback bytes. Your host binding translates between those events and application state.

API surface

| Entry point | Contents | | ----------------------------------------- | ----------------------------------------------------- | | @misofm/control-surface | Complete currently supported API | | @misofm/control-surface/xtouch | X-Touch codec and Web MIDI device | | @misofm/control-surface/xtouch/mcu | Byte-level decode/encode functions and protocol types | | @misofm/control-surface/xtouch/web-midi | Connection lifecycle and device types |

Connection state

WebMidiXTouchDevice#getSnapshot() returns:

interface XTouchDeviceSnapshot {
  supported: boolean;
  status:
    | "unsupported"
    | "idle"
    | "requesting"
    | "searching"
    | "connecting"
    | "connected"
    | "error";
  deviceName: string | null;
  error: string | null;
  sysexEnabled: boolean;
}

Use subscribe() with getSnapshot() directly from React's useSyncExternalStore, another reactive adapter, or an imperative host.

Testing and custom transports

MIDI access and port preference are injectable:

const device = new WebMidiXTouchDevice({
  requestMidiAccess: async () => testMidiAccess,
  preferPort: (port) => port.id === configuredPortId,
});

This is the same seam used by the repository tests; physical hardware is not required for codec or lifecycle coverage.

Architecture

The library keeps the boundaries deliberately narrow:

host application binding
        ↓ semantic mapping
WebMidiXTouchDevice
        ↓ typed MCU events / feedback bytes
Web MIDI ports
        ↓
physical X-Touch

The package owns device and transport behavior. A host owns track banking, fader curves, transport semantics, parameter assignments, display content, and feedback scheduling. This prevents one application's console model from becoming the API for every future hardware driver.

Development

git clone https://github.com/misofm/control-surface.git
cd control-surface
bun install
bun run typecheck
bun run test
bun run build

Tests cover both the byte-level codec and Web MIDI lifecycle, including port open failures. See CONTRIBUTING.md before submitting a hardware-facing change.

Safety and project status

This library does not send firmware and does not include firmware images. Unknown incoming messages are ignored by the typed decoder. Applications remain responsible for deciding when to connect and what feedback to send.

Mackie Control is a proprietary protocol. This implementation is based on public documentation and hardware-tested interoperability references. This project is not affiliated with or endorsed by Behringer, Music Tribe, or Mackie.

License

Licensed under the Apache License 2.0.