Skip to the content.

Developer Guide

This is a brief reference guide to creating a new layout HTML file.

Getting Started

Create an empty HTML file and paste the contents below.

<!DOCTYPE html>
    <title>Touch Midi [My Layout]</title>
    <script src=""></script>

All you need to include in the HTML is the bundled JavaScript in the HTML head, this is served from the jsDelivr CDN, e.g.

Note. You can specify any version tag (see releases) after the touchmidi part, e.g. touchmidi@v2 or touchmidi@v2.2.0 or use touchmidi@latest for the most recent released build

Note. Jan 2020 - There seems to be a bug with jsdelivr CDN and they cache old versions for a VERY long time, it is strongly suggested to use the full version tag, e.g. touchmidi@v2.2.0 in order to get the correct version.

Control Reference

Sliders & Encoders



Creates a slider or encoder control, which holds an underlying value to be sent as CC or NRPN messages. Sliders and encoders start with their value equal to their minimum (zero by default)


One of either cc or nrpn should be specified or the control will do nothing. Both can be specified and the slider will send the value as both CC and NRPN.
If a slider or encoder set to send NRPN also has a max set higher than 127, then a high resolution (14 bit) NRPN value will be sent

Some examples:

<!-- An lime green encoder to control CC 74 -->
<midi-encoder cc="74" label="cutoff" colour="lime"></midi-encoder>

<!-- A slider to control CC 7 with a dynamic label -->
<midi-slider cc="7" label="%v"></midi-slider>

<!-- An encoder which sends a NRPN -->
<midi-encoder nrpn="61,18" colour="#ff00ff"></midi-encoder>

<!-- A horizontal slider with min and max-->
<midi-slider horizontal cc="83" min="20" max="64"></midi-slider>


<midi-button toggle></midi-button>

Creates a button control, which can trigger MIDI messages when pressed and also when it is released. Buttons can be momentary or toggled.


One of either cc, nrpn or note should be specified or the control will do nothing. If multiple are supplied then multiple messages will be sent (e.g. a CC message and and note)

Some examples:

<!-- A button that plays middle C -->
<midi-button note="60" velo="88" label="mid-C" colour="#00ff00"></midi-button>

<!-- A button that opens the filter cutoff fully -->
<midi-button cc="74" value="127" label="filter"></midi-button>

<!-- A mute button toggle -->
<midi-button toggle cc="7" value="0" value-off="127" label="mute"></midi-button>

XY Pad


Creates a 2D touch pad type control, which holds an underlying pair of values to be sent as CC. Pads start with their value equal to their minimum (zero by default)


Note both x & y values share the same min and max

Some examples:

<!-- A XY pad to control filter cutoff and resonance -->
<midi-pad cc-x="74" cc-y="71" label="filter\n%v" colour="magenta"></midi-pad>

Common Attributes

All controls accept the following attributes.

Layout Containers & groups


Create a container which lays out controls in a horizontal row using <group-row>. It is essentially a div set to display: flex and flex-direction: row

  <midi-slider cc="1"></midi-slider>
  <midi-slider cc="2"></midi-slider>


Create a container which lays out controls in a vertical column using <group-column>. It is essentially a div set to display: flex and flex-direction: column

  <midi-slider cc="1"></midi-slider>
  <midi-slider cc="2"></midi-slider>

Row & Column Attributes

Both <group-row> and <group-column> share some common attributes.

Channel Configuration

As described in the user guide layout files can operate in two different ways with respect to MIDI channels. This is likely to change in a future release.

Basic - Single Channel

If designing a layout to control a single device which responds on a single channel (i.e. is mono-timbral) then you do not need to specify any channels (i.e. chan="6) on the controls. Simply omit them and allow the user to pick a global MIDI channel at startup

Advanced - Multi Channel

If designing a layout to control either a device which responds on multiple channels (i.e. is multi-timbral) or you want to control multiple devices, then you must specify the channel using chan= on every control. Any controls without a channel will default to channel 1.
Note. The user can still pick a global channel and override the settings inside the HTML.

Label Formatting

Labels can take the form of a static string, or display a dynamic value taken the control’s parameters. This is done with special flags and specifiers in the label string. These formatters are substituted as follows:

If omitted a label will fall back to showing the value or note number depending on the control


Local development notes.
This project’s dev environment uses Node, NPM and Webpack plus some other tools.

To work locally:

npm install

NPM scripts |Script Name|Purpose| |-|-| |npm run watch|Run webpack bundling with hot reload & dev mode| |npm run build|Create production minified bundle| |npm run lint|Run linting checks with ESLint| |npm run format|Run code format checks with Prettier|

GitHub actions is setup to run a build npm run build and push the results to the latest branch. No development work should take place on this branch