slap_yjs

slap_yjs stores Yjs documents in Durable Streams (slap_streams), as snapshot logs (slap_snapshot_log), and shares presence between the nodes that serve each document.

Use slap_yjs when an Elixir application uses y_ex for collaborative documents and needs a durable update history shared by document servers on different nodes. Your application provides the client connection, forwards sync and awareness messages, and handles authentication. The package does not start a WebSocket or HTTP server. For a log of application-defined changes rather than Yjs updates, use slap_snapshot_log.

Installation

Add slap_yjs to the dependencies in your application's mix.exs:

defp deps do
[
{:slap_yjs, "~> 0.1.0"}
]
end

Run mix deps.get. API documentation is on HexDocs. This package requires OTP 26.2 or later (see Requirements).

Example

In an application that depends on slap_yjs, add these children to its supervision tree, in this order:

children = [
{Slap.Streams.Cluster, store: {:local, "/tmp/slap-yjs"}, shards: 8},
Slap.Yjs.Docs
]

For an application-owned Streams cluster, use the pattern in the slap_streams README and pass cluster: MyApp.StreamsCluster when starting Slap.Yjs.Docs and calling Slap.Yjs.Store. Run one Streams cluster per VM.

Define a document server module:

defmodule MyApp.DocServer do
use Slap.Yjs.DocServer
end

With the supervision tree running, join the document from IEx, which acts as the client process:

iex> {:ok, server} = Slap.Yjs.Docs.join(MyApp.DocServer, {"my-service", "doc-1"}); :ok
:ok
iex> is_reference(Process.monitor(server))
true
iex> :ok = Slap.Yjs.DocServer.sync(server, 5_000)
:ok
iex> {:ok, snapshots} = Slap.Yjs.Store.snapshots({"my-service", "doc-1"}); is_list(snapshots)
true

Pass each Yjs sync or awareness message received from the client to MyApp.DocServer.process_message_v1(server, message, self()). sync/2 waits for local updates to be stored and for the server to catch up with other nodes.

Client behavior

How it works

Requirements

OTP 26.2 or later (mix.exs checks it): the document servers monitor their :pg group, and before 26.2 a process that both monitors and joins a group crashes the :pg scope when it exits.

Tests

mix test

Set SLAP_TEST_S3_ENDPOINT and SLAP_TEST_S3_BUCKET to include the RustFS tests. The multi-node convergence test uses :peer and needs epmd; SLAP_YJS_PROP_SEED replays its edit sequence.

License

Slap is released under the terms of the Apache License 2.0.

Copyright (c) 2026, Michael Russo.