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

Symfony Mailer Command Bundle Laravel Package

inspiredminds/symfony-mailer-command-bundle

A Symfony bundle that adds console commands for testing and debugging Symfony Mailer setups. Send test emails straight from the CLI to verify transports, DSNs, and delivery without writing throwaway code—handy for local development and post-deployment checks.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the bundle:

    composer require inspiredminds/symfony-mailer-command-bundle
    
  2. If you don't use Symfony Flex, register it manually in config/bundles.php:

    return [
        // ...
        InspiredMinds\SymfonyMailerCommandBundle\SymfonyMailerCommandBundle::class => ['all' => true],
    ];
    
  3. Make sure the Symfony Mailer is configured. The bundle does not ship a transport of its own — it sends through whatever your app already has:

    # .env.local
    MAILER_DSN=smtp://localhost:1025
    
    # config/packages/mailer.yaml
    framework:
        mailer:
            dsn: '%env(MAILER_DSN)%'
    
  4. Discover the command:

    bin/console list mailer
    bin/console mailer:send --help
    

    Read --help first — option names (--from, --to, --subject, --body, transport selection, etc.) are the contract you'll script against.

    Note on 1.0.2: the bundle now allows much newer Symfony versions. On Symfony releases that ship the core mailer:test command you will see two mail commands in list mailer. That is expected — they are not equivalent (see below). Check what actually resolved in your lock file, because the relaxed constraint means two environments can now install this bundle against very different Symfony majors:

    composer show inspiredminds/symfony-mailer-command-bundle
    composer why symfony/framework-bundle
    

First use case: send a one-off smoke-test message after setting up MAILER_DSN to prove credentials, TLS, and the envelope are correct before wiring mail into application code:

bin/console mailer:send \
  [email protected] \
  [email protected] \
  --subject="Mailer smoke test" \
  --body="If you can read this, the DSN works."

If that lands, your framework.mailer config is sound and any later failure is application-level, not infrastructure.

Implementation Patterns

mailer:send vs. core mailer:test — pick deliberately. Since 1.0.2 the bundle is installable on Symfony versions that provide mailer:test. The distinction the maintainer calls out matters in practice:

  • mailer:test drives mailer.transports directly — it bypasses the mailer service, so it does not exercise Messenger routing, mailer events, or any decorator/override you registered on the mailer service.
  • mailer:send (this bundle) goes through the mailer service — the same path your application code takes, including Messenger handoff and event listeners.

Use mailer:send when you want to validate your application's mail wiring; use mailer:test when you want to validate a raw transport/DSN in isolation.

Post-deploy / CI smoke test. Run the command against a dedicated inbox in a deploy pipeline or health check. Exit non-zero should fail the job:

bin/console mailer:send [email protected] [email protected] \
  --subject="Deploy $(git rev-parse --short HEAD)" --body="ok" --no-interaction

Debugging local delivery with Mailpit/Mailhog. Point MAILER_DSN at the catcher and send via the command — faster than exercising a registration flow just to see whether mail is produced:

MAILER_DSN=smtp://127.0.0.1:1025

Verifying a specific transport. If you define multiple transports under framework.mailer.transports, use the command to target one explicitly (e.g. a ses transport alongside the default smtp) so you can validate each provider independently rather than only the default. Check --help for the exact transport-selection flag name in your version.

Operational notifications from cron/systemd. For plain-text alerts from shell scripts, the command is a legitimate sendmail-style replacement:

bin/console mailer:send [email protected] [email protected] \
  --subject="Disk usage critical" --body="$(df -h | tail -n +1)" \
  --no-interaction >/dev/null

Guard it behind an app-level check so you never spam on flapping conditions.

Programmatic invocation inside a real console command. When you want a richer email than the CLI accepts (attachments, HTML, Twig-rendered body), don't shell out — build an Email in your own command and inject MailerInterface. Use mailer:send only as the "no-template, raw text" tool.

Extending/overriding behavior. The command is registered as a service, so you can override it in config/services.yaml (same service id, class: pointing at your subclass) or decorate the underlying transport. This is the cleanest extension point if you need default --from values or a --dry-run flag.

Async transports. If your DSN routes through Messenger (e.g. doctrine://default), the command returns success once the message is queued, not delivered. Pair the smoke test with a worker check (bin/console messenger:consume) when validating that path. Note this is exactly the scenario mailer:test cannot cover — it hits transports directly and never enqueues — which is the bundle's main remaining reason to exist on modern Symfony.

Upgrade testing after the 1.0.2 constraint relaxation. Because the Symfony constraint was widened, composer update can silently move this bundle from "installed alongside Symfony 5.x" to "installed alongside a current major" without any code change of yours. Add a smoke-test run of mailer:send to your Symfony upgrade checklist, and keep the --help output assertion (or a scripted invocation) in CI so an option-name change between Symfony generations fails loudly.

Gotchas and Tips

  • License is GPL-3.0, not MIT. This is the single biggest decision point before adopting. For a proprietary SaaS this is often acceptable via network use, but for distributed applications it can force source disclosure. Get sign-off or fork internally; do not treat it as a drop-in like Symfony's MIT components.
  • Overlap with core mailer:test on newer Symfony. Since 1.0.2 you may be installing a bundle that duplicates a first-party command. The maintainer's own justification is that this sends via the mailer service rather than mailer.transports — verify that distinction actually matters for you (Messenger routing, event listeners, mailer decorators). If it doesn't, prefer the built-in command and drop the dependency.
  • Relaxed Symfony constraint = non-reproducible environments. 1.0.2 unlocked higher Symfony versions, so CI and production can resolve different combinations. Keep composer.lock committed, pin the bundle to an exact version, and make sure your CI matrix actually runs the Symfony version you deploy.
  • Very low adoption (2 stars, 0 dependents). Pin an exact version in composer.json, read the handful of source files (the whole package is small enough to audit in minutes), and be prepared to maintain a fork. There is no meaningful community support surface. The bundle's long-term relevance now also depends on whether Symfony's own mail commands close the gap.
  • "From" is not optional in practice. SMTP relays, SES, and most providers reject mail without a valid sender. If you omit --from, expect a transport-level error rather than a friendly validation message.
  • DSN escaping. Special characters in SMTP passwords (@, /, ?, #) must be URL-encoded in MAILER_DSN. A malformed DSN typically surfaces as a connection failure, not a parse error — check with bin/console debug:config framework mailer.
  • The body is raw text. This command sends a plain message, not a Twig-rendered one. If you need HTML or attachments, this is the wrong tool — write a small console command that injects MailerInterface and composes an Email.
  • Don't hide the exit code in scripts. Transport exceptions bubble out and should propagate; avoid || true in cron wrappers or you'll silently lose alerts.
  • Credentials belong in secrets, not .env. Standard Symfony advice, but especially relevant here since the command is often run from deploy scripts where .env files get copied around.
  • Debugging checklist: bin/console debug:container mailer to confirm the mailer is wired, bin/console debug:config framework mailer to inspect the active DSN/transports, and add -v/-vv to the command to surface transport responses where supported.
  • No --dry-run out of the box. If you want validation without delivery, override the command or point MAILER_DSN at a local catcher transport. Note the same applies to mailer:test — it sends for real.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings