Liveflux
Turn a live connection — WebSocket, Phoenix Channels, any push transport — into typed, reconnect-safe UI state. You describe the channel and how its events fold; Liveflux owns the sockets, cache glue, dedup, backpressure, and reconnect logic.
A live, keyed list of trades — the whole component, and it running:
import { useStream } from '@liveflux/react';
type Trade = { id: number; symbol: string; price: number };
export function Trades() {
// upsert → Trade[]: a matching id updates in place, a new id is appended.
const trades = useStream<Trade>({
channel: 'trades',
into: { strategy: 'upsert', key: 'id', cap: 50 },
});
return trades.map((t) => <Row key={t.id} symbol={t.symbol} price={t.price} />);
}The wire subscription is multiplexed onto one connection, deduped, and re-sent after a reconnect — none of which you wrote.
The realtime plumbing it owns
A realtime feature looks small until you ship it. Liveflux is the layer that owns the parts you'd otherwise hand-roll every time — behind a small typed surface.
Reconnect-safe
On an unexpected close it backs off with jitter and replays every active subscription on the new connection — streams resume on their own.
One multiplexed connection
Many subscriptions share a single socket. Identical subscriptions fold once, ref-counted, and release only when the last subscriber leaves.
Cache-shaped state
Fold raw events into the shape your UI renders — append (log), upsert (keyed list), replace (latest), or your own reducer.
Backpressure
Adapters watch the send buffer and queue control frames past a high-water mark; oversized inbound frames are dropped before decoding.
Tear-free React
Reads go through useSyncExternalStore, so state is consistent under concurrent rendering. Pass a selector to re-render only on the slice you use.
Typed end-to-end
Generics flow from the channel through the fold strategy to the value your component receives — the return type follows the strategy.
Protocol- and framework-agnostic
One engine, swappable transports, per-framework bindings. Point it at a new backend by changing the adapter; the components don't move.
Packages
@liveflux/coreFramework-agnostic engine — connection, subscriptions, store, backpressure.
@liveflux/wsGeneric WebSocket adapter for any plain-WebSocket backend, in any language.
@liveflux/phoenixPhoenix Channels (v2) adapter — joins, rejoin backoff, heartbeat topic.
@liveflux/reactReact binding — the useStream hook + LivefluxProvider.
Wire up your first stream
Install three packages, drop in a provider, and call useStream. It's about a dozen lines.