Conquer Uncharted Web App Territory

Conductance is a groundbreaking JavaScript web application server unlike any other.

Why Conductance?

Conductance is built from the ground up on a single unified language and programming model tailored to modern web applications.

Stratified JavaScript

No more asynchronous spaghetti

Straightforward

Instead of manually dealing with callbacks, promises or coroutines, Conductance's Stratified JavaScript base lets you write asynchronous code as if it were synchronous. Even large applications won't end up as unmanageable spaghetti code.

Performant

Conductance is fully asynchronous under-the-hood. Simple high-level language constructs make it easy to compose parallel logic in intuitive ways, allowing you to create highly performant apps.

Robust & Debuggable

The simple sequential programming model makes error handling, recovery and retries a breeze. No manual chaining of error callbacks required. Thanks to the callback-free architecture, stack traces work even across asynchronous calls and can span the client/server boundary.

Compatible

Conductance runs on Node.JS on the server and works with all major browsers. You can dip into the vast JavaScript eco-system and use any existing JavaScript code with Conductance. Want to use your favourite UI library? Or an external JS encryption library? An npm module? No problem.

Surface

Powerful UI framework

Real Code

Surface templates are code, thanks to first-class syntax for templates in StratifiedJS. Not having a separate template language means you can create smart, modular widgets the same way you create reusable code.

Data binding

Builtin support for observables and derived values let you splice dynamic data directly into your UI, with no code required to keep everything up to date.

Look Good, Fast

Boilerplate-free application templates help you prototype apps in a matter of minutes. Integrated Twitter Bootstrap support gives you an immediate jump start towards a good-looking app.

Low Latency

Conductance's support for performing work on the client can dramatically reduce application latency. Try navigating around the Conductance documentation browser for a taste. The interface is constructed in the browser, not on the server.

Bridge

Seamless Real-Time Communication

Real-Time

Conductance breaks down the traditional barrier between client and server and makes 'live' near-real-time applications easy. Instead of writing REST interfaces or wrangling with websocket connections, you can make direct function calls between client and server using Conductance's bridge facility.


All Together Now

Conductance is more than just the sum of its components

Be Productive

With a large curated module library, unified documentation, and only a single language to worry about, you can concentrate on your application logic, rather than spending time making components work together and scouring the web for help.

Dive Under the Hood

While Conductance comes batteries-included, it's easy to strip back the layers and go low-level when you need to. Not happy with the default UI library (Twitter Bootstrap), or prefer to code RESTFUL interfaces rather than use Conductance's bridge? You can pick and choose, or even replace/modify parts to suit your needs.

Open Source & Future-Proof

Conductance is available on GitHub and licensed as Open Source under the GPL, with commercial licensing and support options also available.
Conductance runs anywhere JavaScript runs. The extraordinary status of JavaScript as the world's most widely deployed language ensures that Conductance is built on a firm foundation that is here to last.

What Does Conductance Code Look Like?

Imperative-First

Conductance is based on the philosophy that imperative and not declarative code should be at the top of the app's food chain. Everything starts with a *.app file:

(Hint: click on highlighted code for more information.)

hello.app@ = require('mho:std');

document.body .. @appendContent(
  `<h1>Hello, world</h1>`
);

Hello, world

Declarative built-in

It's not that declarative code is not useful, but the problem is that declarative mechanisms tend to replicate imperative mechanisms. Each declarative language used in your app (ui templates, db query language, server configuaration files) implements the same imperative constructs (like looping or conditionals) all over again with different syntax.

Conductance takes the approach of folding powerful declarative features into the imperative language and not the other way round. This way you only have to learn one language and you can apply the same constructs over and over again for everything in your app, be it business logic or UI.

var squares = @integers(1,100) .. 
                @map(x -> `<tr>
                             <td>$x</td>
                             <td>${x*x}</td>
                             <td>${x*x*x}</td>
                           </tr>`);

document.body .. @appendContent(
  `<table>
     <thead>
       <th>X</th><th>X^2</th><th>X^3</th>
     </thead>
     <tbody>$squares</tbody>
   </table>`);
XX^2X^3
111
248
3927
41664
525125
636216
749343
864512
981729
101001000
111211331
121441728
131692197
141962744
152253375
162564096
172894913
183245832
193616859
204008000
214419261
2248410648
2352912167
2457613824
2562515625
2667617576
2772919683
2878421952
2984124389
3090027000
3196129791
32102432768
33108935937
34115639304
35122542875
36129646656
37136950653
38144454872
39152159319
40160064000
41168168921
42176474088
43184979507
44193685184
45202591125
46211697336
472209103823
482304110592
492401117649
502500125000
512601132651
522704140608
532809148877
542916157464
553025166375
563136175616
573249185193
583364195112
593481205379
603600216000
613721226981
623844238328
633969250047
644096262144
654225274625
664356287496
674489300763
684624314432
694761328509
704900343000
715041357911
725184373248
735329389017
745476405224
755625421875
765776438976
775929456533
786084474552
796241493039
806400512000
816561531441
826724551368
836889571787
847056592704
857225614125
867396636056
877569658503
887744681472
897921704969
908100729000
918281753571
928464778688
938649804357
948836830584
959025857375
969216884736
979409912673
989604941192
999801970299
100100001000000

Live widgets

Quasi-templates can be used for more than just piecing together static HTML. They can also be used to create self-contained 'live' widgets:

var time = @Span() .. 
             @Mechanism(function() {
               while(true) {
                 this.innerHTML = new Date();
                 hold(1000); // wait 1 second
               }
             });

document.body .. @appendContent(`It is $time.`);
It is .

Data binding

Conductance provides Observables - a particularly powerful construct for binding live data into HTML. Observables are just temporal streams of values, and can be manipulated with any of the generic functions from SJS's sequence module.

var name = @ObservableVar('anonymous');

var greet = 
       `<p>You are: $@TextInput(name)</p>
        <p>Hello, $name, your name is
           ${ name .. @transform(x -> x.length) }
           characters long!</p>`;

document.body .. @appendContent(greet);

Structured, composable UI flows

guess.app@ = require(['mho:std','mho:app']);

function dialog(msg, btns) {
  btns = btns .. @map(b->`<button>$b</button>`);
  document.body .. @appendContent(@Div([msg, btns])) {
    |div|
    return (div.querySelectorAll('button') ..
            @wait('click')).target.textContent;
  }
}

while(true) {
  var min = 1, max = 100;

  dialog(`Think of an integer between 
          $min and $max.`,['Ok']);
  while(min != max) {
    var mid = min + Math.round((max-min)/2);
    if(dialog(`Is it smaller than $mid?`, 
               ['Yes', 'No']) === 'Yes')
      max = mid-1;
    else
      min = mid;
  }
  dialog(`Got it: $min!`, ['Again']);
}

Call server API like normal functions

test.api@ = require('mho:std');

exports.uname = function() {
  return @childProcess.exec('uname -a').stdout;
};
test.app@ = require('mho:app');

var api = require('./test.api').connect();

document.body .. @appendContent(
  `Server: <b>${api.uname()}</b>`);
Server: Linux conductance-io 3.9.5-301.fc19.x86_64 #1 SMP Tue Jun 11 19:39:38 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

Bind live data from the server

count.api@ = require('mho:std');
var counter = @ObservableVar(0);

exports.counter = counter;

function background() {
  // emit a value at random intervals < 10s
  while(true) {
    hold(10000*Math.random());
    counter.modify(counter -> counter + 1);
  }
}
// run in background:
spawn background();
count.app@ = require('mho:app');
var api = require('./count.api').connect();

document.body .. @appendContent(
  `Count from Server: <b>${api.counter}</b>`);
Count from Server:

Conductance in Use

For prototyping

Conductance's succinct syntax and unified client/server programming model make it ideal for quick prototyping and proof-of-concept web applications.

For example, to test some of the concepts behind Conductance, we developed 'Oni Matrix' an internal prototype app that offers a spreadsheet-like interface for interacting with web APIs. It allows end-users to create dynamic 'mashup-style' content. Use cases include monitoring applications, data exploration/consolidation from multiple sources and report generation.

In production

Where Conductance really shines is in large-scale applications, such as 'LOGS', a large Conductance-based web application currently rolling out across international academic and industry research facilities.

LOGS manages the data collected in bio-tech spectroscopy laboratories and enables collaboration between the 100s of researchers typically working together on a project.

"Our vision for LOGS was to create a platform that takes full advantage of what modern browsers are able to provide. E.g. one feature of LOGS is an automatic workflow that parses and zips data generated by spectrometers in the browser before uploading to the cloud. We found that workflows like this are incredibly difficult to code with conventional frameworks. Conductance made it incredibly simple."
- Dr. J.J.Lopez, CEO MagicAngle