Phoenix

The official JavaScript client for Phoenix Channels — multiplexed WebSocket realtime with automatic reconnection and presence tracking.

Library
npm
v1.8.13
23,143stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
90/100Excellent
Development Activity96
Maintenance72
Community92
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
86/100Excellent
Architecture87
Code Quality84
Innovation82
Learning Curve90

Phoenix is the official JavaScript client library for Phoenix Channels, the realtime communication layer built into the Phoenix web framework for Elixir. It manages a single multiplexed WebSocket connection to a Phoenix backend, letting you join topic-based channels, push and receive events, and track connected users through the Presence API — all with automatic reconnection, exponential backoff, and a long-polling fallback when WebSockets aren’t available.

Distributed as the phoenix npm package straight from the phoenixframework/phoenix monorepo, this client pairs a small, dependency-free API surface with production-tested reliability: it ships in every new Phoenix project’s asset pipeline and powers realtime features (chat, live dashboards, collaborative editing, presence indicators) across the Elixir ecosystem, while working equally well from any JavaScript frontend regardless of build tool.

What You Get

  • Socket class managing one multiplexed WebSocket connection with automatic reconnect and exponential backoff
  • Channel abstraction for joining topics, pushing events, and handling ok/error/timeout replies
  • Presence helper for syncing and diffing which users/clients are connected to a channel
  • LongPoll transport fallback for environments where WebSockets are blocked or unavailable
  • Pluggable serializers and encode/decode hooks for custom message formats

Common Use Cases

  • Building live chat rooms and comment threads that update instantly for every connected client
  • Powering realtime dashboards and metrics displays pushed from a Phoenix backend
  • Tracking which users are online or editing and showing presence indicators in collaborative apps
  • Streaming server-pushed notifications and events to a JS frontend without polling

Under The Hood

Architecture Phoenix.js is organized as a small set of cooperating ES6 classes rather than a monolithic client: Socket (assets/js/phoenix/socket.js) owns the single WebSocket/LongPoll transport and connection lifecycle, Channel (channel.js) represents one joined topic and delegates message framing to Push (push.js) objects that expose chainable .receive("ok"|"error"|"timeout", cb) hooks, Presence (presence.js) layers a diff-based sync algorithm on top of channel events, and Serializer/Ajax/Timer/constants/utils provide encoding, the long-poll fallback transport, backoff scheduling, and shared constants respectively. Channels register themselves with their parent socket and rely on the socket’s onOpen/onError hooks to drive their own rejoin timers, so reconnection and rejoin logic is decentralized to each channel rather than centralized in the socket — a design that keeps failure handling local to whichever topic actually needs to recover. Because every channel is multiplexed over one socket connection, changing the core Socket class’s message-dispatch contract would ripple through Channel, Push, and Presence simultaneously, making it the one abstraction the rest of the library is built around.

Tech Stack The client is dependency-free vanilla JavaScript (ES6 classes, no runtime dependencies) built from the assets/js/phoenix source tree and published from the same phoenixframework/phoenix monorepo that ships the Elixir framework. The mix assets.build task compiles the JS source into the formats declared in package.json’s exports/main/module/unpkg fields — a CommonJS bundle, an ES module, and a minified UMD build for CDN use via unpkg/jsdelivr. Testing runs on Jest (with jest-environment-jsdom and mock-socket to simulate WebSocket behavior in Node), linting runs through ESLint with the @stylistic and eslint-plugin-jest plugins, and CI runs npm test on Node 24 alongside the Elixir test suite for the wider Phoenix repo.

Code Quality The assets/test/ directory holds six spec files (socket, channel, presence, longpoll, serializer, and socket-over-HTTP tests) totaling roughly 249 test cases covering reconnection backoff, channel join/error/timeout transitions, presence diffing, and the long-poll transport, plus a test.coverage npm script for coverage reporting. Error handling favors explicit state machines over exceptions — Channel and Socket track state via enums (CHANNEL_STATES, SOCKET_STATES) and route failures through onError/onClose callback hooks rather than throwing, which suits a long-lived connection object. Naming is consistent and public classes/methods carry extensive JSDoc comments, though the library ships no TypeScript declaration files of its own — type coverage for TS consumers currently comes from the community-maintained @types/phoenix package rather than from this repo.

API Design The public API optimizes for a small number of composable, chainable primitives rather than configuration objects: joining a channel returns a Push you chain .receive("ok"|"error"|"timeout", cb) calls onto, and the same pattern is reused for every server round-trip (join, leave, custom events), so there’s exactly one interaction idiom to learn. Presence layers a listBy-customizable diff/sync model on top of plain channel events instead of inventing a separate presence protocol, keeping the mental model consistent with the rest of the library. Getting started requires only new Socket(endpoint).connect() and socket.channel(topic) — no build step, framework binding, or scaffolding is required, and automatic reconnection/backoff is opt-out rather than something the caller has to wire up themselves.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search