mpociot/phpws
mpociot/phpws is a lightweight, event-driven WebSocket server for PHP built on ReactPHP. Simple onOpen, onMessage, and onClose callbacks make it easy to add real-time features like chat, notifications, and live updates to your apps.
Feasibility sizing for real-time features. This package turns "can our PHP/Laravel stack do push-style updates without adding a Node.js runtime?" into a concrete, bounded answer. Chat, live notifications, presence indicators, collaborative cursors, live dashboards — all become a 1–2 week spike with known seams (connection lifecycle, handshake auth, reconnection, fan-out) rather than an open-ended platform bet. The PM value is the estimate, not the code: it converts a vague roadmap line into a sized one with a demo attached.
Build vs. buy vs. adopt, for the transport tier. It anchors the lowest-cost, highest-ownership end of the comparison against managed pub/sub (Pusher, Ably) and maintained self-hosted options (Laravel Reverb, Soketi, Centrifugo, Ratchet, Swoole/OpenSwoole). Presenting it as the cheap reference makes the trade-off legible to non-technical stakeholders in one sentence: cheapest to prototype, most expensive to own. That framing is what gets a decision made instead of deferred.
Protocol scope: raw WebSocket vs. topic pub/sub and RPC. If the roadmap anticipates channel-based subscriptions, presence, and remote calls — not just one-way fan-out — the protocol choice constrains the client SDK contract and the channel-authorization model now. This implementation is small enough to read in an afternoon, which makes it unusually good prior art when writing that design doc.
Architecture placement as an explicit roadmap commitment. It only supports the "separately deployed, separately supervised daemon" model. That forces the question early: does real-time live inside the monolith's deploy pipeline, auth, logging, and on-call — or become its own service with its own runbook and its own pager rotation? Answering that late is exactly how a feature quietly becomes a platform obligation nobody budgeted for.
Sequencing and reversibility. The highest-leverage decision this enables is not about the library at all — it is the internal Broadcaster interface: abstract channel subscribe, publish, and presence so no library types leak into domain code. That single decision converts a risky dependency into a timeboxed experiment with a clean exit, and makes every later transport swap a configuration change instead of a rewrite. It is the rare architectural ask that is cheap, legible to stakeholders, and pays off regardless of which vendor wins.
Vendor and dependency risk, recorded as a decision rather than a footnote. Last release May 2019, 28 stars, zero dependents, no maintainer to escalate to. The PM output is a documented call: read it, prototype on it if at all, never route customer-facing or revenue-critical traffic through it. Naming this in the risk register up front is far cheaper than defending it in a security review later.
Low-blast-radius internal bets. Admin consoles, dev-only push channels, and demo harnesses are legitimate uses where the maintenance tax is cheap and the learning value is real. This is also the honest fallback if the spike's value case doesn't hold: keep it as internal tooling, drop the customer-facing ambition, and lose nothing but the timebox.
Stakeholder negotiation leverage. A working prototype is the most persuasive artifact in a budget conversation. "Here is the notification UX, running, for one engineer for two weeks" lands materially differently than a slide deck and a vendor quote.
Consider it when:
Look elsewhere when:
To executives — capability now, dependency later. Real-time is a product capability, not a shopping decision. This package demonstrates the cheapest possible path to it: a PHP-native WebSocket server with no new runtime, no vendor contract, and no external service. It has also been unmaintained since 2019, has no downstream users, and has nobody to escalate to — so it cannot carry customer traffic. Recommendation: fund a one-to-two-week bounded spike using this package as a throwaway harness to prove the real-time UX, and approve the maintained production target in the same decision so the transport isn't relitigated mid-build. The framing is prototype on the cheap, ship on something owned: the spike buys conviction, not infrastructure. Cost of the spike is one engineer for two weeks; cost of skipping the decision is rediscovering all of it during a launch.
To engineering — read it, don't depend on it. Treat mpociot/phpws as a compact reference for WebSocket semantics on ReactPHP. If we vendor it, we own it outright: version pin, security review, named maintainer, and an explicit time budget for patching. The default production proposal is Laravel Reverb or Soketi, with this package cited as prior art in the design doc. The one decision that must not slip is to abstract the transport behind an internal Broadcaster interface so the library choice stays reversible — the auth, TLS proxy, supervisor, and observability work done during the spike then carries over untouched at swap time. The Redis-publish / daemon-subscribe seam is correct regardless of which daemon wins, which is precisely why we should pick a maintained one.
To the team — scope it honestly. The "pure PHP, easy integration" pitch hides a real workstream: an artisan ws:serve command, a process supervisor with a restart policy, a TLS-terminating proxy, handshake authentication, channel authorization, heartbeats, and memory-recycling discipline. None of that is in the box. Estimate it as multi-week before any scaling conversation, and gate the spike with a written acceptance criterion so it cannot quietly slide into production by inertia.
Decisions requested: approve the timeboxed spike; approve the Broadcaster abstraction as a build constraint on the spike; and approve the maintained production target now, so the swap is scheduled and funded work rather than a contingency we discover later.
How can I help you explore Laravel packages today?