A low-latency shared piano for two musicians to jam online.

Fourhands logo

Try Fourhands here.

Explore the source here.

Fourhands, the p2p piano

Fourhands uses WebRTC to establish p2p connections for minimal latency 2-person jamming using MIDI keyboards.

For seamless collaboration on Fourhands, one-way time of 20 ms or less is ideal. Typically this can be achieved on wired connections for fairly nearby players (within 35 miles / 50 km. Anecdotally, a friend has also achieved this between SF and LA – 350 miles / 500 km).

Prior art

Online jamming has been achieved already, but often not in an accessible and unstructured way.

  • Jacktrip allows fairly nearby players to jam in real time, but requires a local machine with a static IP (an AWS instance will not work, since the audio cable must be plugged in to the machine).
  • A few different apps including Endless, NinJam, and Jammr allow collaborative looping, in which your playing is shared n measures after you play it.
  • Jamlink shares audio for remote jamming but requires custom hardware.
  • My own collaborative piano allows multiple participants to share a piano (like Google Docs for piano). The latency is too high to jam, but this does work for sharing ideas when songwriting remotely.
  • See an overview of other options here.

Comparatively, Fourhands is a simple in-browser solution for which all you need is a MIDI keyboard and an optionally wired internet. Because only MIDI data is shared, it is limited to instruments which can output MIDI.


For self hosting, deploy with node index.js debug. This will serve the files needed for the page (index.html and js/) and also start the NodeJs server (index.js).

If you have local SSL keys you can deploy with HTTPS using node index.js. Note that a secure connection is required for MIDI input (localhost is secure by default).

Client should be available at localhost:30001.

Browser support

Chrome and Edge work. Firefox does not work as there is no support for MIDI. Other browsers are not tested, but should work if they support MIDI, Tone.js, web sockets, and WebRTC.