OTP ERLANG Wiregrid Plainwire · Manual 1.0

Manual 1.0

Wiregrid

Wiregrid is a BEAM realtime library for sessions, subscriptions, fanout, presence, rooms, acknowledgements, reconnects, storage, rate limits, and optional clustering. Elixir is the main API. The same runtime is reachable from Erlang through wiregrid_api, from Gleam and LFE bindings, from a Cowboy WebSocket handler, and from non-BEAM programs through a versioned TCP protocol and a C client.

The library keeps product rules outside itself. Users, roles, message schemas, and the product database stay in the embedding application. Wiregrid validates its own inputs, bounds its own tables, and asks an authorizer before a session is allowed to publish, subscribe, join, or signal.

What you need

Elixir 1.17 or newer, on a supported OTP release. The runtime has no mandatory third-party dependency. Postgrex, Redix, Xandra, Cowboy, and StreamData are test-only, so a production release does not pull them in unless the host application already depends on them.

CI compiles the core suite on four pairs: OTP 26.2 with Elixir 1.17.3, OTP 27.3 with Elixir 1.18.4, OTP 28.5 with Elixir 1.20.4, and OTP 29.1 with Elixir 1.20.4. The Cowboy test pin is 2.18 with Cowlib 2.19, because Cowlib 2.20 uses the maybe keyword and does not compile on OTP 26.

Two ways in

For a chat application, define a module with use Wiregrid.Chat and put that module in the supervision tree. connect/3 returns {:ok, session_id}. say/4 persists channel messages. history/3 pages that same stream. whisper/4 addresses {:user, user_id}.

For anything else, call Wiregrid directly: start an instance, connect a session owned by a pid, subscribe to a topic tuple, and publish. Deliveries arrive in the owner process as {:"$wiregrid", envelope}. The envelope carries instance, session_id, delivery_id, topic, class, an optional context, and either event, payload, or both, depending on delivery_format.

How this manual is laid out

The same pages are published at plainwire-development.github.io/Wiregrid. Opening site/index.html from a checkout works without a server: styles, search, and the highlighter are local files.

A short path that already works

defmodule MyApp.Chat do
  use Wiregrid.Chat,
    instance: :chat,
    options: [profile: :small]
end

{:ok, session} = MyApp.Chat.connect("alice")
:ok = MyApp.Chat.join(session, "general")
{:ok, _result} = MyApp.Chat.say(session, "general", "hello")
{:ok, rows, cursor} = MyApp.Chat.history("general", nil, 50)

The generated module’s child_spec/1 starts the instance. Channel messages use the topic {:channel, "general"} and are stored with persist: true and class: :durable. The owner process still has to acknowledge durable deliveries, or the session’s reservation count climbs until the hard queue refuses more work.

Wiregrid 1.0 · Plainwire · github.com/Plainwire-development/Wiregrid