To communicate with the server, use the Waveorb Client.


npm i waveorb-client


For use in the browser, copy the /dist/waveorb-min.js file to app/assets/js and include it in your layout:

<script src="/js/waveorb-min.js"></script>

For use on the server or the command line:

const waveorb = require('waveorb-client')

const api = waveorb('')

The /api at the end is used if you used the waveorb install command to set up your VPS server.

Import the Waveorb client like this if you're using Webpack:

// Include in webpack app
import waveorb from 'waveorb-client'
const api = waveorb('http://localhost:5000')

// As Nuxt plugin, in ~/plugins/waveorb.js
import waveorb from 'waveorb-client'
export default ({}, inject) => {
  inject('api', waveorb('http://localhost:5000'))

// In nuxt.config.js
plugins: [

It works the exact same way in the browser as on the server, it is isomorphic.


The most common way to use the client is over async HTTP Ajax. It initiates a new connection on each request, and gets a result back from your server API actions.

Set it up like this:

// Set up HTTP connection
var api = waveorb('http://localhost:5000')

// HTTP with SSL
var api = waveorb('https://localhost:5000')

// Send through http
var result = await api.action(
    data: {
      values: {
        name: 'Celebration'


When using web sockets you set up a single connection which is re-used for each new request. This has the advantage of being a bit faster and allows you to send data from the server to the browser whenever you need to. As such it is perfect for subscriptions or real-time data.

Waveorb web sockets automatically reconnects on failure, set it up like this:

// Websocket with SSL, needs to await connection
window.socket = await waveorb('wss://localhost:5000')

// Use Promises if you're not in an async function
waveorb('wss://localhost:5000').then(function(socket) {
  window.socket = socket

// Set up websocket connection, with default options shown
var socket = await waveorb('ws://localhost:5000', {
  // Reconnect timeout in ms, set to false to not automatically reconnect
  reconnect: 1000,

  // Ping timeout in ms, set to false to not ping the server
  ping: false,

  // Disconnect timeout when $pong is not received
  disconnect: 3000

// Register events like this
socket.on('open', (event) => {
  console.log('Connection open')

socket.on('close', (event) => {
  console.log('Connection closed')

socket.on('error', (event) => {
  console.log('Connection error')

socket.on('message', (data, event) => {
  console.log('Received message', data)

// Send data to the 'createProject' action and wait for response
var result = await socket.action(
    data: {
      values: {
        name: 'Festival'

Connecting client and server

The action name and parameters in the client matches the server action name and validation. If your server action looks like this:

  createProject: {
    // The data params will be validated like this
    validate: {
      data: {
        name: {
          is: '$string'
    main: async function($) {
      // The data is available in params:

then the client will run the action on the server like this and validate the data parameter:

await api.action('createProject', { data: { name: 'Hello' } })


Uploads are dead simple. Just attach it to a click event in the browser:

function handleUpload() {
  // Upload from browser
  var urls = await api.upload('createProject')
`<button onclick="handleUpload()">`

A file upload dialog will be automatically created in the background. To track the progress, do this:

var urls = await api.upload('createProject', {}, {
  progress: function(event) {
    var { loaded, total, percent } = event

The arguments for the upload function is action name, parameters and options. Options for accept types and selecting multiple files can be be specified like this:

var urls = await api.upload('createProject', {}, {
  // Multiple files
  multiple: true,

  // Only images
  accept: 'image/*'

The files will be available in $.files on the server:

// Array of files, stored in the tmp folder

You can also upload from a script or the command line:

const waveorb = require('waveorb-client')
const api = waveorb('')

// Use the files option to upload to your server
const urls = await api.upload('createProject', {}, {
  files: ['app/assets/file.png']

You can upload multiple files by adding more names to the files array.

CDN, thumbnails and resize

You can set up image manipulation on the server using the dugg library, in case you want to auto-resize, crop and create thumbnails of your images. It uses Jimp for this behind the scenes.

Dugg can also upload your files to Amazon S3. and return the CDN URLs:

// Set up dugg for upload to Amazon S3
const dugg = require('dugg')({
  key: 'amazon_key',
  secret: 'amazon_secret',
  bucket: 'amazon_bucket'

// Jimp options
const config = {
  resize: [120, 120],
  greyscale: []

// Convert files
await dugg.convert($.files, config)

// Upload files to CDN
const urls = await dugg.upload($.files)

// Return URLs to client
return urls