npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@arizona-framework/client

v0.3.1

Published

JavaScript client library for Arizona Framework

Downloads

329

Readme

Arizona

Erlang CI Node.js CI Hex.pm Hex Docs npm version License

arizona logo

Arizona is a real-time web framework for Erlang/OTP. It renders HTML on the server, diffs changes at the template level, and pushes minimal updates to the browser over WebSocket.

Templates are plain Erlang terms compiled via parse transform. The server owns the state; the client is a thin DOM patcher.

🚧 Status

Arizona is in 0.x. The core is functional and covered by tests, but the API may change between minor versions. Pin an exact version in your deps (e.g. {arizona, "0.1.0"}) if you need stability across upgrades.

Features

  • SSR + live updates -- HTML on first load, WebSocket diffs after
  • Erlang-native templates -- {Tag, Attrs, Children} tuples compiled by parse transform
  • Compile-time static/dynamic split -- statics sent once, only dynamics cross the wire
  • Three handler kinds -- arizona_view (route pages), arizona_stateful (components), arizona_stateless (pure templates)
  • Streams -- keyed collections with insert/delete/update/move/sort/limit
  • SPA navigation -- az_navigate links, server renders the next page over WebSocket
  • PubSub -- cross-view, cross-tab messaging via arizona_pubsub
  • Route middlewares -- gate or rewrite requests before mount (auth, sessions, URL projection)
  • On-mount hooks -- per-route pipeline that runs before every mount, including navigate
  • Element hooks -- client-side mounted/updated/destroyed callbacks via az_hook
  • Dev-mode hot reload -- fs watcher recompiles changed .erl files and pushes reload events
  • Pluggable transport -- cowboy adapter built-in; write your own to swap it out

Requirements

  • Erlang/OTP 28 or later

Installation

Add Arizona to your rebar.config dependencies. Cowboy is required for the built-in HTTP/WebSocket transport; skip it only if you write your own arizona_req adapter.

{deps, [
    {arizona, "~> 0.1"},
    cowboy
]}.

To track unreleased changes, swap the version for a git ref:

{arizona, {git, "https://github.com/arizona-framework/arizona.git", {branch, "main"}}}

The client JavaScript ships baked into the rebar3 build (priv/static/assets/js/*.min.js). If you need to bundle it yourself or consume it from a non-Erlang backend, install via npm:

npm install @arizona-framework/client
import { connect } from '@arizona-framework/client';

connect('/ws');

Quick start

A page with an embedded counter.

1. The counter component

id and initial count come from the parent via ?stateful (step 2), so mount/1 just passes them through:

%% src/my_counter.erl
-module(my_counter).
-include_lib("arizona/include/arizona_stateful.hrl").
-export([mount/1, render/1, handle_event/3]).

mount(Bindings) ->
    {Bindings, #{}}.

render(Bindings) ->
    ?html(
        %% id must be on the root element -- if it changes, the component is remounted
        {'div', [{id, ?get(id)}], [
            {button, [{az_click, arizona_js:push_event(~"dec")}], [~"-"]},
            {span, [], [~" Count: ", ?get(count), ~" "]},
            {button, [{az_click, arizona_js:push_event(~"inc")}], [~"+"]}
        ]}
    ).

handle_event(~"inc", _Payload, Bindings) ->
    {Bindings#{count => maps:get(count, Bindings) + 1}, #{}, []};
handle_event(~"dec", _Payload, Bindings) ->
    {Bindings#{count => maps:get(count, Bindings) - 1}, #{}, []}.

?get(count) registers count as a dependency of that template slot. When handle_event returns new bindings, only slots whose tracked keys changed re-render -- the <span> patches; the buttons don't.

The tuples carry more than just bindings: mount/1 returns {Bindings, Resets} (an explicit slot-reset map -- usually #{}), and handle_event/3 returns {Bindings, Resets, Effects} where Effects is a list of arizona_js commands (set_title, navigate, …) executed on the client.

2. The parent page

A view is the route's root handler. It receives initial bindings plus the request:

%% src/my_page.erl
-module(my_page).
-include_lib("arizona/include/arizona_view.hrl").
-export([mount/2, render/1]).

mount(Bindings, _Req) ->
    {Bindings, #{}}.

render(Bindings) ->
    ?html(
        {main, [{id, ?get(id)}], [
            {h1, [], [~"Counter demo"]},
            %% id is required -- it's how the diff engine routes patches to this component
            ?stateful(my_counter, #{id => ~"counter", count => 0})
        ]}
    ).

3. The layout

The HTML shell. Loads the client runtime that connects over WebSocket:

%% src/my_layout.erl
-module(my_layout).
-include_lib("arizona/include/arizona_stateless.hrl").
-export([render/1]).

render(Bindings) ->
    ?html([
        ~"<!DOCTYPE html>",
        {html, [], [
            {head, [], [
                {meta, [{charset, ~"utf-8"}]},
                {title, [], [?get(title, ~"Arizona")]}
            ]},
            {body, [], [
                ?inner_content,
                {script, [{type, ~"module"}], [
                    ~"""
                    import { connect } from '/assets/arizona.min.js';
                    connect('/ws');
                    """
                ]}
            ]}
        ]}
    ]).

4. Configure the server

Add arizona to your app's applications list in .app.src:

{applications, [kernel, stdlib, cowboy, arizona]}

Then declare routes in config/sys.config:

[{arizona, [
    {server, #{
        routes => [
            {live, ~"/", my_page, #{
                layouts => [{my_layout, render}],
                bindings => #{id => ~"page", title => ~"Counter demo"}
            }},
            {ws, ~"/ws", #{}},
            {asset, ~"/assets", {priv_dir, arizona, "static/assets/js"}}
        ]
    }}
]}].

5. Run it

rebar3 shell

Open http://localhost:4040 and click the buttons -- the server renders the initial HTML, then pushes minimal diffs over WebSocket as the count changes.

Documentation

See docs/architecture.md for the full architecture reference -- module breakdown, op codes, dev-mode file watchers, custom schemes/proto_opts, and imperative startup.

Sponsors

If you like Arizona, please consider sponsoring me. I'm thankful for your never-ending support ❤️

I also accept coffees ☕

"Buy Me A Coffee"

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for development setup, testing guidelines, and contribution workflow.

Contributors

Star History

License

Copyright (c) 2023-2026 William Fank Thomé

Arizona is open-source under the Apache 2.0 License on GitHub.

See LICENSE.md for more information.