node package manager
Easy collaboration. Discover, share, and reuse code in your team. Create a free org »

haplo

haplo

haplo lets you write both your front-end and back-end in the same JavaScript codebase.

// main.js 
haplo.server(function() {
    var data = 'foobar';
    haplo.client(function(data) {
        alert(data);
    })(data);
});

The data variable will only exist on the server and be retrieved by the client via AJAX on load. It works by compiling it down to separate files, one for each end, and automatically setting up routes for the transition between contexts.

$ haplo main.js
// client.js 
haplo.server(1, function (data) {
    alert(data);
});
// server.js 
haplo.on(1, function () {
    var data = 'foobar';
    haplo.client(data);
});

Installation

1. Install haplo globally

$ npm install --global haplo

2. Install haplo in your project

$ npm install haplo

3. Create main.js in the project's root

// app/main.js 
var haplo = require('haplo');
 
console.log('Sending request to server');
haplo.server(function() {
    console.log('Request catched by server, responding to browser');
    haplo.client(function() {
        console.log('Response catched by client, roundtrip done');
    });
});

4. Create a public folder with an index.html

<!-- app/public/index.html -->
<script src="dist/bundle.js"></script> <!-- bundle.js will be generated by the haplo command -->

5. Run haplo

$ haplo

6. Done!

Your application is now live at http://localhost:3000.

Fire it up and have a look at the browser's console as well the terminal window where haplo is running. You should see that the console messages are printed in their respective environments.

Example

A simple example app with a MongoDB backend. Input is validated both on the client and server.

// app/main.js 
var haplo = require('haplo');
 
var form = document.forms[0];
 
form.addEventListener('submit', function(e) {
    e.preventDefault();
 
    var itemName = form.elements[0].value;
   
    if (/[^A-Za-z0-9]/.test(itemName)) {
        alert('Item name may only contain alphanumerics');
        return;
    }
    
    haplo.server(function(itemName) {
        if (/[^A-Za-z0-9]/.test(itemName)) {
            return;
        }
   
        var mongo = require('mongodb').MongoClient;
      
        var uri = 'mongodb://myuser:mypass@ds028017.mongolab.com:28017/mydb';
      
        mongo.connect(uri, function(err, db) {
            db.collection('items').insert({name: itemName}, function(err, items) {
                haplo.client(function(id) {
                    alert('Item was added with id ' + id);
                })(items[0]._id);
            });
        });
    })(itemName);
});
<!-- app/public/index.html -->
<!doctype html>
<html>
<head><title>Haplo Example</title></head>
<body>
    <h1>Add item</h1>
    <form>
        <input type="text" placeholder="Item name">
        <input type="submit" value="Add">
    </form>
    <script src="dist/bundle.js"></script> 
</body>
</html>