View on GitHub


WebSocket Application Server

Download this project as a .zip file Download this project as a tar.gz file

N2O: Erlang Application Server

Build Status


Optional Dependencies

N2O comes with BERT message formatter support out of the box, and you only need one N2O dependency in this case. Should you need DTL templates, JSON message formatter, SHEN JavaScript Compiler or NITRO Nitrogen DSL you can plug all of them in separately:

{n2o,    ".*",{git,"git://",         {tag, "2.8"}}},
{nitro,  ".*",{git,"git://",       {tag, "2.8"}}},
{shen,   ".*",{git,"git://",        {tag, "1.5"}}},
{jsone,  ".*",{git,"git://",    {tag,"v0.3.3"}}},

Message Formatters

You can use any message formmatter at the bottom of N2O protocol. IO messages supported by the N2O protocol are as follows:

1. BERT : {io,"console.log('hello')",1}
2. WAMP : [io,"console.log('hello')",1]
3. JSON : {name:io,eval:"console.log('hello')",data:1}
4. TEXT : IO console.log('hello') 1\n
5. XML  : <io><eval>console.log('hello')</eval><data>1</data></io>

Besides, you can even switch a channel termination formatter on the fly within one WebSocket session.

All Features in One snippet


peer()    -> io_lib:format("~p",[wf:peer(?REQ)]).
message() -> wf:js_escape(wf:html_encode(wf:q(message))).
main()    -> #dtl{file="index",app=n2o_sample,bindings=[{body,body()}]}.
body() ->
    {Pid,_} = wf:async(fun(X) -> chat_loop(X) end),
    [ #panel{id=history}, #textbox{id=message},
      #button{id=send,body="Chat",postback={chat,Pid},source=[message]} ].

event(init) -> wf:reg(room);
event({chat,Pid}) -> Pid ! {peer(), message()};
event(Event) -> skip.

chat_loop({Peer, Message} ) ->
       wf:insert_bottom(history,#panel{body=[Peer,": ",Message,#br{}]}),
       wf:flush(room) end.


ab, httperf, wrk and siege are all used for measuring performance. The most valuable request hell is created by wrk and even though it is not achievable in real apps, it can demonstrate internal throughput of certain individual components.

The nearest to real life apps is siege which also performs a DNS lookup for each request. The data below shows internal data throughput by wrk:

Framework Enabled Components Speed Timeouts
PHP5 FCGI Simple script with two <?php print "OK"; ?> 5K timeouts
ChicagoBoss No sessions, No DSL, Simple DTL 500 no
Nitrogen No sessions, No DSL, Simple DTL 1K no
N2O All enabled, sessions, Template, heavy DSL 7K no
N2O Sessions enabled, template with two variables, no DSL 10K no
N2O No sessions, No DSL, only template with two vars 15K no

Kickstart Bootstrap

To try N2O you need to clone a N2O repo from Github and build it. We use a very small and powerful tool called mad designed specially for our Web Stack.

$ git clone git://
$ cd n2o/samples
$ ./mad deps compile plan repl

Now you can try it out: http://localhost:8000

LINUX NOTE: if you want to have online recompilation you should install inotify-tools first:

$ sudo apt-get install inotify-tools

Erlang version

We don't accept any reports of problems related to ESL or Ubuntu packaging. We only support Erlang built from sources, official Windows package, built with kerl or installed on Mac with homebrew. If you have any problems with your favourite Erlang package for your OS, please report issues to package maintainer.

Posting Issues on Github

Thank you for using N2O (you've made a wise choice) and your contributions to help make it better. Before posting an issue on Github, please contact us via the options listed below in the support section. Doing so will help us determine whether your issue is a suggested feature, refactor of existing code, bug, etc, that needs to be posted to GitHub for the contributing development community of N2O to incorporate. DO NOT post issues to GitHub related to misuses of N2O, all such issues will be closed.



If you are new or you need to decide whether the N2O architecture and philosophy is a fit for your project

Windows Users

For windows you should install and appropriative packages to use Synrc Stack: