Arizona is a real-time web framework for Erlang that delivers high-performance web applications through compile-time optimization and differential rendering.
Work in progress.
Use it at your own risk, as the API may change at any time.
Compile-time template optimization. Arizona's parse transforms optimize templates at compile time, not runtime. Templates are analyzed, diffed, and reduced to efficient rendering functions before your application ever starts.
Differential rendering. Only the parts of the page that actually changed are sent over the wire. Combine this with compile-time optimization and you get minimal network traffic and minimal browser work.
Three template syntaxes. Write templates as HTML strings, pure Erlang terms (with full editor support and type safety), or GitHub Flavored Markdown with embedded expressions — whichever fits the use case.
Built on the BEAM. Lightweight live processes for every connected client. PubSub backed by
Erlang's built-in pg — no Redis needed. Fault tolerance and hot code upgrades come free from OTP.
Real-time and static in one framework. Build interactive real-time apps with WebSocket-driven live updates, then generate static HTML from the same views for SEO and deployment flexibility.
- Compile-time template optimization via parse transforms
- Differential DOM updates minimizing network traffic
- Real-time WebSocket updates with automatic synchronization
- Multiple template syntaxes: HTML, Erlang terms, Markdown
- Type-safe stateful and stateless component hierarchy
- Static site generation for SEO and deployment flexibility
- Request-reply events (callEvent/callEventFrom) alongside fire-and-forget
- PubSub system using Erlang's built-in pg
- Unified middleware system for all route types
- Plugin system for configuration transformation
- Smart CSS-only reload preserving application state
- Editor support with Neovim plugin and Tree-sitter grammar
Add Arizona as a dependency and create your first view.
In your rebar.config:
{deps, [
{arizona, {git, "https://github.com/arizona-framework/arizona", {branch, "main"}}}
]}.-module(home_view).
-behaviour(arizona_view).
-compile({parse_transform, arizona_parse_transform}).
-export([mount/2, render/1, handle_event/3]).
mount(_Arg, _Request) ->
arizona_view:new(
?MODULE,
#{
id => ~"home",
greeting => ~"Hello, Arizona!",
count => 0
},
none % No layout
).
render(Bindings) ->
arizona_template:from_html(~"""
<div id="{arizona_template:get_binding(id, Bindings)}">
<h1>{arizona_template:get_binding(greeting, Bindings)}</h1>
<p>Clicked: {arizona_template:get_binding(count, Bindings)} times</p>
<button onclick="arizona.pushEvent('increment')">Click me</button>
</div>
""").
handle_event(~"increment", _Params, View) ->
State = arizona_view:get_state(View),
Count = arizona_stateful:get_binding(count, State),
NewState = arizona_stateful:put_binding(count, Count + 1, State),
{[], arizona_view:update_state(NewState, View)}.For configuration, layouts, and next steps, see the Getting Started guide.
Try the complete working examples:
# Clone and run the test server
$ git clone https://github.com/arizona-framework/arizona
$ cd arizona
$ ./scripts/start_test_server.shThen visit:
- http://localhost:8080/counter - Simple stateful interactions
- http://localhost:8080/todo - CRUD operations and list management
- http://localhost:8080/modal - Dynamic overlays and slot composition
- http://localhost:8080/datagrid - Sortable tables with complex data
- http://localhost:8080/realtime - Real-time PubSub updates and live data
- http://localhost:8080/blog - Markdown template processing with Arizona syntax
- http://localhost:8080/ - Static blog home page
- http://localhost:8080/about - Static about page
- http://localhost:8080/post/hello-world - Dynamic blog post routing
- http://localhost:8080/post/arizona-static - Blog post about Arizona static generation
Each demo corresponds to complete source code in
test/support/e2e/:
- Counter
App
- Layout + View with event handling and PubSub integration
- Todo App
- Complex state management and CRUD operations
- Modal System
- Component composition, slots, and dynamic overlays
- Data Grid
- Advanced data presentation and sorting functionality
- Real-time
App
- Live data updates and WebSocket communication
- Blog App
- Markdown template processing with Arizona syntax integration
- Static Blog
- Static site generation with layouts and dynamic routing
For additional examples and real-world usage patterns, check out the dedicated example repository:
- Arizona Example
- Complete application examples and patterns
- Getting Started — Installation · Quick Start · Project Structure
- Templates — Overview · HTML · Erlang Terms · Markdown · Bindings
- Components — Overview · Views · Stateful · Stateless · Layouts · Slots · Collections
- Events — Overview · WebSocket · Call Events · PubSub · Client Events
- Actions — Actions
- Server — Configuration · Routing · Middleware · Plugins
- JavaScript Client — Setup · Logging
- Deployment — Production · Static Site
- Development — File Watching · Smart Reload
- Ecosystem — Editor Support · Examples
- Erlang/OTP 28+
- arizona.nvim - Neovim plugin for development
- tree-sitter-arizona - Tree-sitter grammar for Arizona templates
If you like this tool, please consider sponsoring me. I'm thankful for your never-ending support ❤️
I also accept coffees ☕
Contributions are welcome! Please see CONTRIBUTING.md for development setup, testing guidelines, and contribution workflow.
Copyright (c) 2023-2026 William Fank Thomé
Arizona is 100% open-source and community-driven. All components are available under the Apache 2 License on GitHub.
See LICENSE.md for more information.

