Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Whatsapp Laravel Package

kstmostofa/laravel-whatsapp

Dual-backend WhatsApp for Laravel: a pure-PHP Meta Cloud API client plus a whatsapp-web.js sidecar for personal-number access, unified under one WhatsApp:: facade, with a Livewire admin UI, Eloquent models, webhooks, and health checks.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit The package is a conventional Laravel integration — service provider, config publish, migrations, WhatsApp:: facade, queued job, events, Artisan commands — plus two optional surfaces: a Livewire/Flux admin UI and a bundled Node sidecar. That shape fits a Laravel monolith or modular monolith cleanly. It does not fit a polyglot/service-oriented stack, a serverless/container-per-request platform, or anything where you cannot run a persistent Node process under Supervisor.

The strategic issue is that this is really two products under one API:

Cloud API backend Web sidecar backend
Nature Official Meta Graph API client Browser automation of WhatsApp Web
ToS posture Supported, compliant Gray area, explicit ban risk
Runtime None beyond PHP Node + Chromium (~600 MB), persistent process
Scalability Horizontal, millions Session-bound
Unique value Templates, verified sender Personal number, groups, status, free-form sends

The facade's WhatsApp::send() auto-routing by recipient shape (+9665… vs 9665…@c.us) is convenient but is also an implicit backend decision made at the call site. As a TPM I would treat that as a leaky abstraction to be constrained in code review, not a feature to lean on.

Integration feasibility

  • Cloud API path: genuinely low effort. Composer install, three env vars plus app secret and verify token, one webhook route, one queued job. Days, not weeks.
  • Sidecar path: materially harder. A one-time ~600 MB Chromium download in the build/deploy pipeline, a Node runtime on the host, a long-running SSE listener (whatsapp:web:listen) per session under Supervisor/systemd, and QR pairing as a human-in-the-loop step.
  • UI path: optional and separable. Three CSS modes (Tailwind v4, standalone precompiled ~32 KB, headless) means we can adopt the facade and skip the UI entirely without forking.

Technical risk

  1. Account risk (highest). The sidecar automates a personal WhatsApp account against WhatsApp's terms. The realistic downside is not a package bug — it is a banned business number and lost customer conversation history. This must be an explicit, signed-off business decision with a dedicated non-critical number, never the primary support line.
  2. Upstream fragility. Release v1.0.3 exists specifically because WhatsApp Web minified its internals and whatsapp-web.js broke — messages arriving with id: null and /chats returning {"error":"r"}. That is a structural property of browser automation, not a one-off. Expect recurring, unannounced breakage with a fix latency bounded by a single volunteer maintainer.
  3. Maintainer/bus factor. One author, 242 stars, 0 dependents, one 1.0.x release line, 46 tests / 133 assertions. Low ecosystem validation is the honest read on the "opportunity: 15.24" score. We should assume we may need to fork and self-maintain the sidecar.
  4. Dual-backend surface area. Two credential sets, two webhook/event paths, two failure taxonomies, two identity formats (E.164 vs @c.us/@g.us). Every message-handling code path has a backend branch.
  5. Security defaults are decent but require action. HMAC verification fails closed with 503 if WHATSAPP_APP_SECRET is unset (good); sidecar binds to 127.0.0.1 with a bearer token (good); but /whatsapp/* ships without auth middleware and only logs a warning in production. That is ours to configure, not theirs.

Key questions for the vendor/author (or our own discovery)

  • Is our WhatsApp Business account verified, and do we have a permanent system-user token rather than a 24-hour test token?
  • What is the actual send volume and template mix? If it fits Cloud API templates, the sidecar buys us nothing.
  • Which features are genuinely required that Cloud API cannot serve — groups, status, or free-form outside the 24-hour window? Get this in writing from the business owner.
  • What number would the sidecar pair, and who accepts the ban risk?
  • Does the hosting target allow a persistent Node process and a 600 MB Chromium artifact?
  • Who owns patching when whatsapp-web.js breaks — us or the maintainer, and with what SLA?
  • Is WHATSAPP_DB_CONNECTION isolation required by our data-residency/retention policy for message content?

Integration Approach

Stack fit Laravel 11/12/13, PHP 8.2 (8.4 required on Laravel 13 due to Symfony 8), Livewire 3/4 and Flux only if we want the UI. Broadcasting is opt-in (WHATSAPP_BROADCAST=true) and pulls in Reverb/Pusher/Ably — treat as a phase-3 nicety, not a prerequisite. Everything is MIT-licensed, so forking is legally unencumbered.

Recommended posture: Cloud-first, sidecar-optional, headless-first.

Migration path Greenfield — no legacy data to move. The only migration decisions are:

  • Whether to enable WaSession/WaMessage/WaContact persistence at all, or keep our own domain tables and consume the events. I lean toward consuming events into our own schema so the package stays a transport, not a system of record.
  • If we do adopt their models, use WHATSAPP_DB_CONNECTION to isolate message content on a separate connection with its own retention policy.
  • v1.0.0 → v1.0.3 is a pure composer update (no migrations, no config, no API changes), which is a good sign for patch-level upgrade friction.

Compatibility

  • Pin the package in composer.json and pin PHP/Laravel in CI against the supported matrix.
  • Use WHATSAPP_UI_CSS_MODE=standalone if we adopt the UI — it ships precompiled CSS served only on /whatsapp/*, so it cannot collide with our Tailwind/Bootstrap/Vite pipeline. This is the single best integration decision available here.
  • Skip livewire/flux entirely if we go headless; the facade, events, jobs, webhook receiver, and commands all work without it.

Sequencing

Phase Scope Gate to proceed
0 Spike: Cloud API sandbox send + template + inbound webhook → our event listener Meta business verification complete; permanent token issued
1 Production Cloud API: templates for transactional messaging, SendMessage job on queue, HMAC webhook behind our middleware, whatsapp:health --json --exit-code wired into monitoring p95 send latency and template approval rate acceptable
2 Optional UI at /whatsapp behind our auth middleware, standalone CSS, separate DB connection Support/ops team confirms it replaces an existing tool
3 Sidecar pilot, isolated: dedicated SIM, 127.0.0.1 binding, strong WHATSAPP_WEB_TOKEN, Supervisor per session, alerts on session drop Business owner signs off on ban risk; fallback comms channel live
4 Scale/broadcasting: bulk send (currently unbuilt), Reverb Only if volume justifies it

Note that "bulk send job with rate limiting" is an unchecked roadmap item. If broadcast/marketing messaging is in scope, we are building that ourselves — do not plan around it.

Abstraction guidance Wrap the facade behind our own NotificationChannel interface with sendTemplate() and sendText() as the only methods we call. Do not let WhatsApp::send()'s recipient-shape routing appear in application code. This gives us a clean exit to Twilio, 360dialog, or a BSP if the package stalls.

Operational Impact

Maintenance

  • Cloud backend: near-zero. Graph API versions roll; we track them and bump the package.
  • Sidecar backend: an ongoing operational commitment. Two moving parts we do not control — WhatsApp Web's DOM/internals and whatsapp-web.js's compatibility — plus a Chromium binary we must keep patched for CVEs independent of the package's release cadence.
  • Assume we fork the sidecar within 12 months. Budget ~0.2–0.3 FTE of backend time for sidecar upkeep during pilot, with spikes whenever WhatsApp ships a Web change (see v1.0.3: two breakages in one patch release).

Support

  • One maintainer, issue-driven, responsive on the evidence (v1.0.3 credits a specific reporter and backfills missing changelogs — a good signal). But there is no commercial support, no SLA, and 0 dependents means we are close to the only production user.
  • The docs site is real (VitePress, production guide, troubleshooting, UI screenshots), which is above average for a 242-star package. That reduces ramp-up cost meaningfully.

Scaling

  • Cloud API scales the way you'd expect: stateless HTTP, queue workers, backoff on 429s. The job's "no retry on permanent Meta error codes" behavior is correct and saves us from poisoning the queue.
  • Sidecar does not scale. One Chromium session per paired number, one whatsapp:web:listen process per session, session state on local disk. It is a single-instance component and dictates that our deployment target has persistent local storage and cannot be a stateless autoscaling group.
  • Broadcasting adds Reverb/Pusher and a websocket tier to the ops surface. Only justified if the Livewire UI is actually used by humans in volume.

Failure modes to instrument before launch

Failure Symptom Mitigation
WhatsApp Web minification change id: null messages, /chats returning {"error":"r"} Alert on sidecar 5xx rate and null-ID insert rate; keep pinned whatsapp-web.js version
QR session expiry / logout Sidecar silently stops receiving whatsapp:health --json --exit-code in cron + page ops; treat as PagerDuty-class
Chromium crash / OOM Process dies, PID file stale Supervisor restart + whatsapp:sidecar:status check
Missing WHATSAPP_APP_SECRET Webhook returns 503 fail-closed — inbound silently dead Config lint at boot in CI; assert in healthcheck
Missing UI auth middleware /whatsapp publicly readable, contains customer conversations Set ui.middleware in config; add a deploy-time assertion
Duplicate rows on no-ID messages Inflated conversation counts v1.0.3 inserts instead of upserts; reconcile by (from, body, timestamp)
Meta 24-hour window / template rejection Sends fail with permanent codes, no retry Route marketing copy through approved templates only; surface rejections to business owner
Sidecar account ban Number disabled, history lost Dedicated non-primary number; parallel email/SMS fallback; feature-flag kill switch
Single-maintainer abandonment No fixes for upstream breakage Fork rights under MIT; keep the package behind our own interface

Ramp-up

  • Cloud-only, headless: a mid-level Laravel developer is productive in under a day. The README quick-start is accurate and the mental model is one facade plus one job.
  • Adding the UI: another half-day, mostly auth middleware and CSS mode.
  • Adding the sidecar: a full sprint including deploy pipeline changes, process supervision, monitoring, QR pairing runbook for ops, and a documented recovery procedure for "the number stopped working."

TPM recommendation Adopt the Cloud API backend in production now — it is low-risk, well-scoped, and removes a real integration cost. Treat the web sidecar as a separate, gated pilot with a dedicated number and an explicit, written acceptance of ToS/ban risk; do not merge it into the critical path. Ship headless first and only enable the Livewire UI if a named team will actually use it. Keep the package behind an internal notification interface so that a stalled maintainer, a WhatsApp Web change, or a Meta policy shift is a swap rather than a rewrite.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics
robbiep/afterthedeadline
frankkessler/incontact-laravel-oauth2-rest
jlxh/laravel-userlog
davidmgilo/timetables
qylinfly/role-permission
reflect-digital/conduit
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr