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

System Mail Bundle Laravel Package

hautzi/system-mail-bundle

Symfony bundle for sending system-generated emails with configurable templates and mail transport integration. Use a simple service API to dispatch transactional notifications, confirmations, and other automated messages from your application.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Headline finding: this is not a Laravel package. hautzi/system-mail-bundle is a Symfony bundle. It ships a *Bundle class registered through Symfony's kernel, relies on Symfony's DI container and compiler passes, and (circa 2018) almost certainly targets Swiftmailer plus Doctrine ORM entity mapping. Laravel uses Symfony components (symfony/mailer, symfony/console, symfony/http-foundation) but not the framework — there is no bundle loader, no config/bundles.php, no autowired compiler-pass lifecycle. Direct installation via Composer will "succeed" and produce nothing usable.

Architecture fit — poor. The value proposition is narrow and well-defined: a service that resolves and sends localized "system mails" (password reset, welcome, receipt) from stored templates, selecting the template by code + recipient locale with fallback. That concept fits Laravel cleanly; the implementation does not. Laravel already covers most of the capability natively: Mailable::locale() sets the locale for a single send, lang/{locale}/ files hold translations, and Mail::to()->locale()->send() handles the fallback chain. The bundle's only genuine differentiator is database-backed, admin-editable templates — that is the piece worth porting, and it is maybe 200 lines of Laravel code.

Integration feasibility — low as-is, moderate as a re-implementation. Effort to make the bundle load in Laravel: not viable at any reasonable cost. Effort to port the concept: 1–2 sprints for a single engineer including tests, admin UI optional.

Technical risk — high, and mostly not about functionality:

  • Abandoned. Last release December 2018. Swiftmailer reached end-of-life in November 2021 and was removed from Symfony; the send path is likely non-functional on any current stack.
  • Zero dependents, 18 stars. No production validation, no issue-tracker signal, no third party to ask about edge cases. This is a greenfield unknown, not a proven component.
  • SSTI surface. Database-stored email bodies rendered through Twig (or Blade, post-port) are an injection vector if any non-engineer can edit templates. Any port must sandbox rendering or restrict editing to trusted roles.
  • PHP constraint. 2018-era composer.json almost certainly pins PHP 7.x and Symfony 3/4 — it will conflict with a modern Laravel dependency graph rather than merely fail at runtime.

Key questions to resolve before any decision:

  1. Do we actually need database-editable templates, or is "localized transactional email" the real requirement? If the latter, Laravel covers it today and this package is moot.
  2. Who edits copy — engineers via PR, or marketing/support via an admin panel? Only the second answer justifies building anything.
  3. Which locales, and what is the mandatory fallback chain (user locale → app locale → en)? Does the business accept a silent English fallback on a German invoice email?
  4. Volume and queue topology — are these mails sent inline in request handlers or queued?
  5. Is there a compliance requirement (audit trail of which template version was sent to whom) that a DB-backed model would satisfy and lang files would not?

Recommendation: do not adopt. Do not fork either — owning an abandoned Symfony bundle inside a Laravel codebase is a permanent tax. Port the schema and resolver contract, not the code.

Integration Approach

Stack fit. Target Laravel 10/11 on PHP 8.2+, symfony/mailer via Laravel's Mail facade, Blade or Markdown mailables, queue-backed sending. The only artefact carried over from the bundle should be its data model and resolution semantics.

Proposed port shape:

  • system_mails table: code (e.g. auth.password_reset), locale, subject, body_html, body_text, version, updated_by, timestamps. Unique index on (code, locale).
  • SystemMailTemplate Eloquent model with a render(array $params) method.
  • SystemMailer service: send(string $code, array $params, Notifiable $to, ?string $locale = null) — resolves the template, walks the fallback chain, throws a loud MissingMailTemplateException rather than silently degrading (unless the fallback chain explicitly terminates in a configured default locale).
  • A SystemMailMessage Mailable that accepts rendered subject/body and sets ->locale() so Laravel's own translation layer handles any residual strings.
  • Admin editing behind a permission gate, with rendering sandboxed to an allowlist of variables ({{ $user->name }}, {{ $action_url }}) — not arbitrary Blade.

Migration path. There is no data to migrate from the Symfony bundle — no dependents exist and we are not running it. The real migration is from whatever we do today: hardcoded mailables, hardcoded English strings, or ad-hoc lang files.

Compatibility. Laravel's mail API is stable across 10/11; Symfony Mailer transport config is unchanged. The one compatibility trap is queue serialization of a Mailable holding rendered HTML — keep the Mailable small and re-render inside the job if the payload grows.

Sequencing.

  1. Audit (week 1). Inventory every transactional email, its trigger, its current locale handling, and its owner. This is the step that determines whether the port is worth doing at all.
  2. Prototype with native Laravel (week 1). Implement two or three emails as plain Mailables with lang files and ->locale(). Measure how much pain remains.
  3. Decide. If the residual pain is "copy changes require a deploy," proceed to step 4. If not, stop here — you have spent a week and saved a quarter.
  4. Build the template layer (weeks 2–3). Schema, resolver, fallback chain, admin UI, audit columns.
  5. Migrate by code, not by big bang. Move one mail code at a time behind a config flag; keep the old path live until the new one has sent successfully in production for a full release cycle.
  6. Decommission. Delete the old mailables and their strings; do not leave two paths.

Operational Impact

Maintenance. This is the dominant cost and the reason to decline the dependency. A fork means owning a Symfony bundle's worth of code forever, in a codebase where no one has Symfony framework expertise. The ported version is smaller but still ours: template rendering, fallback semantics, and the admin surface all become internal products requiring owners, tests, and documentation.

Support. Zero upstream support. The repository's last commit predates the Swiftmailer removal, so any issue found in the original code has no path to a fix. Our ported version is supported by whichever team owns transactional messaging — name that team before starting.

Scaling. Effectively a non-issue. Email sending is I/O-bound and low-volume relative to typical Laravel workloads. Put sends on a queue, cap concurrency against the SMTP provider's rate limit, and the template resolution (one indexed DB read per send) is noise. Cache resolved templates per (code, locale) with invalidation on write if volume ever justifies it — it likely never will.

Failure modes to design against:

  • Missing template/locale. Silently sending English to a German customer is a support ticket; throwing at send time in a password-reset flow is an outage. Resolve this deliberately: fail loudly in staging and CI (a test that asserts every code has every supported locale), fall back with an alert in production, and log the degraded send.
  • Render exception. A malformed admin edit should break one mail code, not the request that triggered it. Wrap rendering in the queued job, catch, log, and alert — never let a template error 500 a checkout.
  • Unescaped interpolation. User-supplied params (names, order titles) rendered into HTML must be escaped by the renderer, not by the template author. Make escaped-by-default the only mode.
  • Queue backlog. Transactional mail competing with bulk mail on the same queue is a classic. Use a dedicated queue and connection.

Ramp-up. Low for the ported version — any Laravel developer can pick up an Eloquent model, a service class, and a Blade view in a day. High, bordering on unacceptable, for the original bundle: it would require Symfony DI literacy that this team has no other reason to hold.

Bottom line. The problem the package names is real and recurring; the package itself is not the answer in a Laravel codebase. Spend one week proving that native Laravel mailables plus lang files are insufficient, and only then build the small internal template layer the concept actually requires.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console