Nitrogen Elements is a HTML template engine for Erlang language where all HTML tags are being rendered from Erlang records.

With N2O you don’t need to use HTML at all. Instead you define your page in the form of Erlang records so that the page is type checked at the compile time. This is a classic CGI approach for compiled pages and it gives us all the benefits of compile time error checking and provides DSL for client and server-side rendering.

Nitrogen elements, by their nature, are UI control primitives that can be used to construct Nitrogen pages with Erlang internal DSL. They are compiled into HTML and JavaScript. Behavior of all elements is controlled on server-side and all the communication between browser and server-side is performed over WebSocket channels. Hence there is no need to use POST requests or HTML forms. I.e.

#textbox { id=userName, body= <<"Anonymous">> }, #panel { id=chatHistory, class=chat_history }

will produce

<input value="Anonymous" id="userName" type="text"/> <div id="chatHistory" class="chat_history"></div>


Nitrogen Actions is a JavaScript template engine for Erlang language where all events and button reactions are being rendered from Erlang language.

nitro:update(loginButton, #button{id=loginButton, body="Login",postback=login,source=[user,pass]});

This will produce the following HTML:

<input value="Login" id="loginButton" type="button"/>

and JavaScript code:

qi('loginButton').outerHTML='<button id=\"loginButton\" type=\"button\">Login</button>';{var x=qi('loginButton'); x && x.addEventListener('click',function (event){ event.preventDefault(); { if (validateSources(['user','pass'])) { ws.send(enc(tuple(atom('pickle'),bin('loginButton'), bin('b840bca20b3295619d1157105e355880f850bf0223f2f081549dc 8934ecbcd3653f617bd96cc9b36b2e7a19d2d47fb8f9fbe32d3c768866 cb9d6d85700416edf47b9b90742b0632c750a4240a62dfc56789e0f5d8 590f9afdfb31f35fbab1563ec54fcb17a8e3bad463218d6402f1304'), [tuple(tuple(string('loginButton'),bin('detail')),[]), tuple(atom('user'),querySource('user')), tuple(atom('pass'),querySource('pass'))]))); } else console.log('Validation Error'); }});};


NITRO supports streaming of prerendered forms over WebSocket and MQTT and provides tiny JavaScript library to work with document model. This library is compatible across implementations.

-spec render(list(#element{})) -> binary(). -spec wire(list(#action{})) -> []. -spec insert_top(atom(), list(#element{})) -> []. -spec insert_bottom(atom(), list(#element{})) -> []. -spec update(atom(), list(#element{})) -> []. -spec clear(atom()) -> []. -spec remove(atom()) -> []. -record(init, { token = [] :: [] | binary() }). -record(pickle, { source = [], pickled=[], args=[] }). -record(flush, { data = [] :: [] | term() }). -record(direct, { data = [] :: [] | term() }). -record(ev, { module = [] :: [] | atom(), msg = [] :: [] | term(), trigger= [] :: [] | atom() | binary(), name = [] :: [] | atom() | binary() }).