Oni Conductance is a Javascript-based application server for creating rich web applications with a single, powerful language across the client and server.

Note: This is an early release of Conductance, and there may be some teething issues. We appreciate your patience, and if you do run into trouble please let us know either via email or at the GitHub Issues page.


The current Conductance version is 0.5.1.

Fresh Install

Linux OSX

For OSX and Linux, pop open a terminal window and run the following command:

curl https://conductance.io/install.sh | bash -e

For Windows, download and run the appropriate self-installer:

32-bit (.exe) / 64-bit (.exe)

This will install Conductance into ~/.conductance/, and optionally add a shortcut in /usr/bin/conductance (OSX / Linux) or add itself to your $PATH (Windows).

For more details and other installation methods, see the advanced installation page.


To update a previously installed Conductance server to the most recent version, run:

conductance self-update

Safety check

All of Conductance's functionality is exposed through the conductance executable. To check that everything is installed properly, run:

conductance version

That should print the version of Conductance and its components to your terminal.

If you opted out of a global installation, you'll instead need to run conductance using its full path:

~/.conductance/bin/conductance version

(You can instead add conductance to your $PATH manually, instructions are on the advanced installation page)

Jump in

If you want to get straight into the details of building a Conductance appliation, you can head straight to the tutorial:

Build a multi-user chat application

Otherwise, read on for an overview of Conductance.

Conductance basics

Conductance's primary purpose is to be used as a server for web applications, but you can also use it to run arbirtary server-side Stratified JavaScript code, or as a general purpose webserver. Let's start with the latter.

Conductance as a webserver

Open a terminal, cd into any directory of your choice and type:

conductance serve

By default, this will serve the current directory on port 7075, which you can easily verify by navigating your browser to http://localhost:7075/. For more information on how you can customize where, what, and how things are served see the documentation for .mho file format.

Interactive Shell

To open an interactive Conductance shell, run:

conductance shell

You will be presented with a prompt at which you can enter and execute JavaScript code:

console.log("Hello, world")
Hello, world
function hello(name) { console.log("Hello, "+name); }
Hello, Oni

This prompt will let you run any code that work in the server-side (nodejs) environment. You can also use the online prompt (available as test/console.app in the Conductance source code), which will let you run any code that works in a browser. The majority of the StratifiedJS libraries work in both environments, but there are a number of modules that only make sense in one environment (e.g filesystem access or DOM manipulation).

Getting to know StratifiedJS

Conductance's super-charged JavaScript implementation - Stratified JavaScript - has many enhancements over conventional JavaScript. Some of these are syntax enhancements that make programming more concise and pleasant, e.g. arrow notation (->), string interpolation (" #{...} "), and double dot call syntax (x .. f):

var hello = name -> "Hello, #{name}!"
"StratifiedJS" .. hello
'Hello, StratifiedJS!'

Find out more in the SJS language syntax docs.

What really distinguishes Stratified JavaScript from normal JS (and from all other mainstream programming languages for that matter) is that it is built around a whole new way of thinking about how to program with concurrency. The idea is quite simple: All of the language's existing control structures "just work" - no matter whether they are doing something asynchronous under the hood or not. In practice you rarely need to think about this. You can just program as if everything was synchronous, e.g.:

var site_length = url -> @http.get(url).length;
var site_war = (a,b) -> "#{a} is #{site_length(a) < site_length(b) ? "smaller" : "larger"} than #{b}";
site_war("http://google.com", "http://apple.com")
'http://google.com is smaller than http://apple.com'

At this point you might say "Hang on, there's nothing exciting here; this is just plain-old synchronous programming as we've been doing it in Python, Ruby, [insert language] for ages". Only it's not. StratifiedJS can concurrently do other things while it is waiting for asynchronous operations, and it has powerful operators to orchestrate the overall logic.

E.g. if you only want to wait for a maximum of 100ms for the result of site_war(.):

waitfor { site_war("http://google.com", "http://apple.com") } or { hold(100); console.log("Timeout") }
Timeout (unless maybe if you live up the road from Google and Apple)

Here, under the hood, the waitfor/or construct will cleanly abort the pending calls to Google and Apple if there's a timeout. This is because, similar to exceptions, SJS allows cancellation of a computational stratum to be "caught" and handled using the try/retract (or try/finally) construct. All of the built-in functions, work as you would expect when they are cancelled: in the case of @http.get, a retraction will cause the request itself to be aborted.

The cancellation/retraction mechanism is a very powerful feature of StratifiedJS. It allows us to build up very complicated asynchronous programs in a modular, compositional way without ending up with asynchronous spaghetti. And because it is automatic, and all low-level built-ins know "what to do" when retracted, most of the time you don't really need to think about it or do anything special in your code.

Exploring the Standard Library

StratifiedJS provides a cross-platform module system. It's similar to the require() function in nodejs, but better:

  • It works the same in both browser and server-side code
  • It operates asynchronously, allowing you to load modules while other things are happening

And of course since this is StratifiedJS, you don't have to jump through hoops just because it's asynchronous:

var seq = require('sjs:sequence');
[1, 2, 3] .. seq.each(console.log);

This loads the sequence module, and uses its each function to iterate over a list. The code works the same on a server and in a browser.

Generally, require loads modules from URLs, because that's the common way of specifying resources across environments. But Conductance defines two prefixes (known as hubs):

  • sjs: the StratifiedJS standard library
  • mho: the Conductance standard library

On the server, these will be aliased to file:// URLs based on the installation path, while in a browser these will be http:// or https:// URLs to the appropriate location on your server. When loading modules that are part of your app, you will typically pass a relative url to require(), rather than specifying a full URL.

In Conductance applications, you will typically use both - sjs: provides a large number of modules containing functionality that you might expect in a language's standard library, while mho: provides additional modules specific to building web applications.

You can view the full documentation for all Conductance and StratifiedJS modules using the online documentation browser.

Because it takes work to require and assign all of the individual modules that an application makes use of, Conductance provides a mho:std module which combines and re-exports the most useful modules from both StratifiedJS and Conductance. With this, you can typically start a script or application with:

@ = require('mho:std');

..and you'll have access to functions from many modules, including the sequence functions that we used above:

[ 1, 2, 3 ] .. @each(console.log);

(if you're curious about that @ symbol, it's known as the alternate namespace)

Build your first app

We've covered the basics, it's time to build something! If you haven't already followed the multi-user chat tutorial, this is a good time to get started:

Build a multi-user chat application

Further reading

The next step is to start writing your own code, with the documentation browser at your side. We've done our best to document everything we think you'll need, including not just API documentation but also a StratifiedJS language reference and an overview of Conductance features. Please let us know if you find the documentation unclear, or if there's not enough information on a given topic.