Product Decisions This Supports
- Build vs. buy for dev/test SMS plumbing: This package answers a narrow question — "how do we exercise SMS notification paths in development without paying per-message or risking real sends to real handsets?" It is not a product feature; it is a cost and risk control for the engineering pipeline behind SMS features (OTP/2FA, order updates, appointment reminders, delivery tracking). The buy decision is essentially free (MIT), but the integration cost is the real budget line, and in a Laravel codebase that cost is non-trivial.
- Roadmap scoping for SMS-dependent features: If the roadmap includes any SMS-triggered journey, the team needs a way to demo and QA that journey end-to-end before a carrier contract exists. A fake transport (email inbox or log file) unblocks demos, PM-led acceptance testing, and staging walkthroughs without procurement of a Twilio/Vonage account.
- Vendor/abstraction validation: The DSN pattern (
fakesms+email://... vs. a real transport DSN) is a useful forcing function. It makes the PM ask engineering early: "Is our SMS layer swappable per environment?" If swapping fake for real requires a code change rather than a config change, that is a design gap worth fixing now, on the cheap, before the first real provider lands.
- QA and automated-test strategy: Choosing log-based output over email-based output is a product-adjacent decision about what "testable" means — log assertions are cheap in CI, email assertions require a mail sink. This shapes how confidently the team can claim SMS journeys are covered.
- Deliberate non-adoption as a decision: The most likely correct PM outcome is to adopt the pattern, not the package — implement a similarly simple fake channel inside Laravel's
Notification system (a log or mail driver channel), which costs a day and avoids pulling Symfony Notifier in. Framing it that way keeps the conversation about the goal (fake SMS in dev) rather than the artifact.
- Not a differentiator: With 27 stars, 0 dependents, and a release history dominated by "no significant changes," this is infrastructure hygiene, not a product bet. It should never appear on a roadmap or a customer-facing narrative. It belongs in the engineering "definition of done" for SMS work.
When to Consider This Package
Adopt — or more precisely, allow — this package when most of the following are true:
- You are already on Symfony Notifier. If the application (or a shared service in the same estate) already dispatches through
symfony/notifier with transport DSNs, adding symfony/fake-sms-notifier is a one-line .env change and near-zero risk. This is the clean case and the only one where direct adoption is obviously rational.
- You need SMS notification output in a place product and QA can actually read without touching a real gateway — a shared dev inbox or a log file both satisfy "I can see what the customer would have received."
- You want per-environment swap via configuration only, so that staging can point at a real provider while local points at the fake, with no branching logic in application code.
- You are pre-procurement. Vendor contracts, sender-ID registration, and carrier approvals take weeks. A fake transport lets feature work and UAT proceed in parallel with procurement instead of blocking on it.
- You accept the version coupling. Symfony 8.x requires PHP ≥ 8.4; the 6.4/7.x lines cover older runtimes. Pin deliberately and expect to track Symfony's release cadence.
Look elsewhere — or build a 50-line in-house fake channel — when:
- You are a standard Laravel shop. Laravel's
Illuminate\Notifications system does not consume Symfony Notifier transports. Bridging requires a custom channel adapter plus a service binding, which is more code than simply writing a LogSmsChannel or MailSmsChannel against Laravel's own abstractions. The dependency weight (symfony/notifier and its transitive tree) is real and buys you nothing you can't write yourself.
- Your test strategy is mock-based. If CI already fakes the SMS gateway at the HTTP or client layer (or uses notification fakes), a fake transport is redundant surface area.
- You need fidelity the fake cannot give. No delivery receipts, no carrier filtering, no rate limiting, no character-encoding/segmentation behaviour, no real latency. Fake SMS proves your code path fires; it proves nothing about deliverability, cost per segment, or how a 3-segment Unicode message renders on a low-end Android device. Do not let "SMS tested" mean "SMS validated."
- There is any risk of it reaching production. A dev-only transport in a config-driven system is one bad
.env merge away from silently black-holing real OTPs. If you cannot guarantee environment isolation (config validation, boot-time assertion, deployment gate), the package's convenience becomes a safety liability.
- Governance is strict about dependency count or vendor surface — a 27-star, 0-dependent, "no significant changes" package is a fine convenience and a poor critical path.
How to Pitch It (Stakeholders)
One line for the exec/roadmap audience: This is a free, MIT-licensed development tool that lets us build and demo SMS features — OTP, order updates, reminders — before we've signed a carrier contract or spent a cent on per-message fees. It is not customer-facing and carries no commercial risk.
The business case, in three points:
- Speed. SMS feature work starts now instead of after procurement. Messages route to a developer inbox or log file during development, so the journey is visible and reviewable end-to-end.
- Cost and safety. Zero spend on test messages, zero risk of paging a real customer's phone during QA, and zero chance of a demo firing live traffic at a real handset.
- Reversibility. It is a configuration switch, not an architecture. We point at the fake in dev, at a real provider in staging and production. If it disappoints, we delete the dependency.
For engineering, the honest caveats:
- We are a Laravel shop; this is a Symfony bridge. It does not plug into
Illuminate\Notifications without a thin adapter we write ourselves. Recommendation: adopt the pattern, not necessarily the package — a small in-house fake SMS channel gives us the same outcome with fewer moving parts and no version coupling to Symfony's release train.
- It is explicitly dev-only. The pitch must include a hard guarantee that it cannot be configured in production — an environment assertion at boot, or a deploy-time check. "Silent SMS black hole in prod" is the one failure mode that could turn a harmless dev tool into an incident, and it's the failure mode stakeholders will ask about.
- What it does not prove: real deliverability, per-segment cost, carrier filtering, or handset rendering. QA sign-off on SMS must still include a small, budgeted round of real-device testing against the production provider. Do not let a green test suite substitute for that.
The ask: a small engineering allowance (roughly a day) to either wire up the fake transport or build the equivalent in-house channel, plus agreement that "SMS journeys are demoable and testable in dev" becomes part of the definition of done for any SMS-dependent roadmap item. No procurement, no vendor, no customer impact.