Arizona Fundamentals
So far our blog renders HTML on the server and sends complete pages to the browser. For real-time interactivity — updating a comment section without a page reload, live form validation, instant notifications — we need something more. Arizona is a real-time web framework for Erlang, inspired by Phoenix LiveView, that brings server-rendered interactivity to Nova applications.
Arizona requires OTP 28+. Check your Erlang version with erl -eval 'io:format("~s~n", [erlang:system_info(otp_release)]), halt().' -noshell.
What Arizona does
Arizona keeps a persistent WebSocket connection between the browser and the server. When state changes on the server, Arizona:
- Computes which parts of the HTML changed (differential rendering)
- Sends only the changed parts over the WebSocket
- The client patches the DOM using morphdom
No full page reloads. No client-side framework. The state lives on the server in an Erlang process.
How it works under the hood
Arizona uses compile-time template optimization via Erlang parse transforms. When you write a template:
render(Bindings) ->
arizona_template:from_html(~"""
<h1>Hello, {arizona_template:get_binding(name, Bindings)}!</h1>
<p>You have {integer_to_list(arizona_template:get_binding(count, Bindings))} messages.</p>
""").
At compile time, Arizona:
- Parses the template into static and dynamic segments
- Tracks which variables each segment depends on
- Generates code that only re-renders segments whose dependencies changed
This means when count changes but name doesn't, only the second <p> is re-rendered and sent to the client.
Templates use OTP 28 sigil strings (~"..." or ~"""...""" for multi-line). Dynamic expressions are wrapped in {...} inside the template. All Arizona modules must include -compile({parse_transform, arizona_parse_transform}). for the template system to work.
Adding Arizona to your project
Add the dependency to rebar.config:
{deps, [
nova,
{kura, "~> 1.0"},
{arizona_core, {git, "https://github.com/Taure/arizona_core.git", {branch, "main"}}}
]}.
Add arizona_core to your application dependencies in src/blog.app.src:
{applications,
[kernel,
stdlib,
nova,
kura,
arizona_core
]},
Template syntax
Arizona supports three template syntaxes. The HTML sigil string syntax is the most common:
%% Embedded Erlang expressions with {...}
arizona_template:from_html(~"""
<div class="post">
<h2>{arizona_template:get_binding(title, Bindings)}</h2>
<p>{arizona_template:get_binding(body, Bindings)}</p>
</div>
""")
Expressions inside {...} are evaluated at render time and tracked for differential updates. Use arizona_template:get_binding/2 to access bindings with automatic dependency tracking.
The connection lifecycle
- Browser requests a page — Nova renders the initial HTML and sends a full page
- Arizona's JavaScript client opens a WebSocket connection
- The server spawns an
arizona_liveGenServer for this connection - User interactions trigger events sent over the WebSocket
- The server processes events, updates state, and pushes DOM diffs back
- The client patches the DOM
Each connected user has their own server-side process holding their state — true server-rendered interactivity.
Next, let's build our first live view in Live Views.