Web server for participative art performances and installations.


rhizome is a web server for participative performances and installations.

rhizome is a solution for transmitting messages and files between OSC applications, web pages, midi devices, ... therefore allowing you to control the user's devices with your installation, or allowing the participants to control your installation with their smartphones, computers or tablets.

rhizome was used to realize the following projects : https://github.com/sebpiq/rhizome/wiki/Gallery

The simplest and nicest way to do this is probably by installing nvm. You can also download an installer directly from Node.js website.

Open a terminal, and simply run npm install -g rhizome-server. If this succeeded, you can try to run rhizome. This should print rhizome help message.

A sample configuration file with all available options can be found here, you can use it to get started.

Say you have created a configuration file called myConfig.js. You can now start the server by running rhizome myConfig.js in your terminal.

Now that the server is running, the only thing left is to create your application by programming a few clients for rhizome. There is a full example here, providing bare bones for a web page (and websocket client), a Pure Data client and a SuperCollider client.

If you have any feedback, any problem, if you need help, don't hesitate to drop a message in the issue tracker.

Also, if you would like to add your rhizome project to the gallery, please contact me.

Simple communication protocol. The rhizome server receives connections from different clients (OSC, websockets, ...) and allows them to communicate together through a protocol that looks a lot like OSC :

/some/address ["big", "bang"]
/other/address [1.123456, Blob(100000)]

Publish / Subscribe. To receive messages sent at a given address, a client has to subscribe to that address. This avoids all messages to be sent to all clients, and therefore offers an optimized yet flexible messaging system.

OSC support. Any OSC client such as Pure Data, Max/MSP, SuperCollider, Processing, ... is supported out of the box.

example | OSC API

websocket support. A websocket client is included with rhizome. It can be used in your web pages, and handles all the dirty bits of websocket communication : automatic reconnection and so on ...

example | websocket client API

Transferring files over OSC. While file transfer (or binary data transfer) is not supported by many OSC clients, rhizome provides a simple tool called rhizome-blobs to handle this. This allows you to receive / send files from / to any OSC client through rhizome.


Static web server. rhizome can serve static web pages, HTML, JavaScript, CSS, ... so that you don't have to setup a separate HTTP server yourself.


Reliability. Crashes shouldn't happen, but in case they do, your server can be restarted cleanly, and its whole state will be restored.

The following messages are used for communication between one connection and the server

  • /sys/subscribe <appPort> <address> : subscribes the OSC client running at <appPort> to all messages sent at <address>.
  • /sys/resend <appPort> <address> : resends the last message sent at <address> to the OSC client running at <appPort>.
  • /sys/blob <appPort> <address> <blobPath> [<arg1> <arg2> ...] : sends the file <blobPath> from an OSC application to the server using rhizome-blobs.
  • /sys/config <appPort> <parameter> [<arg1> <arg2> ...] : sends configuration for the OSC client running at <appPort> to the rhizome server. Available parameters are :
    • blobClient [<blobsPort>] : tell the server that the OSC client uses rhizome-blobs for file transfers. blobsPort is the port on which rhizome-blobs is listening for incoming files. If not provided a default value will be chosen.
  • /sys/subscribe <address> : subscribes the web client to messages sent at <address>
  • /sys/resend <address> : resends the last message sent at <address>.

The following messages are sent by the server. To receive them, you should subscribe to them.

  • /broadcast/open/<namespace> <id> : a user connected to the web page, his id is <userId>
  • /broadcast/close/<namespace> <id> : user with id <userId> left the web page

This event is sent when the client successfully connected (or re-connected) with the server.

This is the event you need to listen in order to receive messages. For example :

rhizome.on('message', function(addressargs) {
  if (address === '/background/color') setBgColor(args[0])

This event is sent when connection fails because the server is full.

rhizome.on('queued', function() {
  showMessage('Waiting for an available space')
rhizome.on('connected', function() {

Emitted when the connection to the server has been lost. You can use this e.g. to deactivate the user interface if the device is not connected anymore :

rhizome.on('connection lost', function() {
  showMessage('Reconnecting ... be patient')

Starts the client, and executes done(err) when complete. The fact that the client is started, doesn't mean that the client is connected. For example, if the server is full, the connection is queued.

Sends a message to address, with an optional list of arguments args. For example :

rhizome.send('/ring', ['wake up', 8.0])

This is a helper to limit the number of messages sent to the server. Sending too many messages, too fast, might overload the network and cause the system to be unresponsive. This function can help you tackle this issue by forcing callback(value) to be called at most every time milliseconds. Example :

// Let's assume for the sake of the example, the function `onMouseMove` 
// is called every 5 milliseconds each time the mouse moves. 
// We don't want to send all those messages, so we're gonna use 
// `rhizome.utils.throttle` to send every 100 milliseconds instead. 
var sendValue = rhizome.utils.throttle(100, function(xy) {
  rhizome.send('/mouse/xy', xy)
var onMouseMove function(xy) {
  sendValue([x, y])

Returns true if the current browser is supported, false otherwise.

Unique id of the client. It is null if the web client is not connected.

export DEBUG=rhizome*

You need to install mocha for running the tests and istanbul for the test coverage :

npm install -g mocha
npm install -g istanbul

Then from the root folder of the project, run tests like so :

npm test

And generate a coverage report like so :

npm run coverage
  • 0.6.0

    • Completely reorganized structure of the library
    • websockets.Client :
      • 'queued' event instead of 'server full'
      • start just returns an error if server is full and queueIfFull is false
    • Server should now be able to restart nicely and restore its full state after crash or normal stop.
  • 0.5.2

    • Exposed clients and servers so that library can be used as a package
    • Server:
      • moved OSC server/clients to a separate library node-moscow
      • Refactored servers to implement Server and Connection base classes.
      • fixed a bug causing server to crash when blob client refuses connection
  • 0.5.1

    • Server: fixed a bug with gulp
  • 0.5.0

    • Server:

      • option clients removed. Now OSC connection are created on the fly instead of being declared in the config file.
      • building the web client with gulp instead of grunt
    • Blob client:

      • option appPort removed. Clients don't need to be declared anymore
      • option fileExtension to save files with a given extension
  • 0.4.3

    • web client:
      • bug fixes
  • 0.4.2

    • Server:
      • bug fixes
  • 0.4.0

    • get the last message sent to an address by sending to /sys/resend

    • Web client:

      • subscribing now happens by sending to /sys/subscribe
      • receiving a message by listening to 'message' event
      • events 'connected', 'server full', 'connection lost', 'reconnected'
      • added utils.throttle function
      • added isSupported to test browser support
    • Server : added different transports (TCP, UDP) for OSC.

  • 0.3.2

    • Web client:

      • added utils.throttle to limit messages sent to server
      • added isSupported to test browser support
      • sends connection lost and reconnected events
      • debug renamed to log
    • Server : more robust UDP connection handling

  • 0.3.1

    • Server:

      • now sends messages to /broadcast/websockets/open and /broadcast/websockets/open when a websocket connection is opened or closed
    • Web client:

      • throws an error if trying to send invalid args
  • 0.3.0

    • App clients:

      • clients must now subscribe by sending to /sys/subscribe
      • to send a blob, now clients must send to /sys/blob
    • Web client:

      • blobs are now handled like any other argument
      • can now both send and receive blobs
      • message renamed to send
      • listen renamed to subscribe
    • Bins:

      • config is now validated and displayed when starting the binaries
  • 0.2.0

    • Web client:

      • removed blob, now blob sent with message
      • renamed client.config.retry to client.config.reconnect
    • Blob client for sending blobs web client <-> OSC

    • Added address validation

  • 0.1.1

    • Fixed bugs with retry
    • In web-client : added client.status()
  • 0.1.0 Initial release