Application email in Symfony moves through message-building code and the configured Mailer transport. A small console command that sends one welcome message proves the application can create an Email object, hand it to MailerInterface, and reach the selected transport before the same pattern is used in a controller, form handler, or background job.

MailerInterface is the application service that hands an Email object to the configured transport. The Mailer DSN decides where the message goes, so a local catcher such as Mailpit keeps development sends visible without reaching real recipients.

Projects created with the webapp recipe may route Mailer messages through Messenger. Keeping the local transport synchronous during the smoke test makes the message appear in the catcher immediately; production apps can switch back to an async transport and run a worker.

Steps to send email with Symfony Mailer:

  1. Start a local Mailpit SMTP catcher.
    $ docker run --detach --name mailpit --publish 1025:1025 --publish 8025:8025 axllent/mailpit

    Port 1025 accepts SMTP mail from Symfony. Port 8025 serves the Mailpit web UI and API for checking captured messages.

  2. Point the development Mailer transport at Mailpit.
    MAILER_DSN=smtp://127.0.0.1:1025
    MESSENGER_TRANSPORT_DSN=sync://

    Use MESSENGER_TRANSPORT_DSN=sync:// only for a local smoke test when the project routes Mailer messages through Messenger. Remove it or restore the async DSN before testing queue workers.
    Related: How to configure Symfony Mailer
    Related: How to configure a Symfony Messenger queue

  3. Create the console command class that sends the message.
    <?php
     
    namespace App\Command;
     
    use Symfony\Component\Console\Attribute\AsCommand;
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputArgument;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    use Symfony\Component\Mailer\MailerInterface;
    use Symfony\Component\Mime\Email;
     
    #[AsCommand(
        name: 'app:send-welcome-email',
        description: 'Send a welcome email through Symfony Mailer.',
    )]
    final class SendWelcomeEmailCommand extends Command
    {
        public function __construct(private readonly MailerInterface $mailer)
        {
            parent::__construct();
        }
     
        protected function configure(): void
        {
            $this->addArgument('recipient', InputArgument::REQUIRED, 'Recipient email address');
        }
     
        protected function execute(InputInterface $input, OutputInterface $output): int
        {
            $recipient = (string) $input->getArgument('recipient');
     
            $email = (new Email())
                ->from('app@example.com')
                ->to($recipient)
                ->subject('Welcome to Example App')
                ->text('Your Symfony Mailer setup can now send application email.');
     
            $this->mailer->send($email);
     
            $output->writeln(sprintf('Sent welcome email to %s', $recipient));
     
            return Command::SUCCESS;
        }
    }

    Move the same MailerInterface injection into a controller or service when the real application action should send the message.
    Related: How to create a Symfony console command

  4. Clear the Symfony cache after adding the command or changing local mailer settings.
    $ php bin/console cache:clear
    
     // Clearing the cache for the dev environment with debug true
    
     [OK] Cache for the "dev" environment (debug=true) was successfully cleared.
  5. Send the welcome message from the command.
    $ php bin/console app:send-welcome-email reader@example.net
    Sent welcome email to reader@example.net
  6. Check the captured message in Mailpit.
    $ curl -sS http://127.0.0.1:8025/api/v1/messages
    {
      "total": 1,
      "messages": [
        {
          "From": {"Address": "app@example.com"},
          "To": [{"Address": "reader@example.net"}],
          "Subject": "Welcome to Example App",
          "Snippet": "Your Symfony Mailer setup can now send application email."
        }
      ]
    }

    The same message should also appear in the Mailpit inbox at http://127.0.0.1:8025.

  7. Remove the temporary Mailpit container when the smoke test is finished.
    $ docker rm --force mailpit
    mailpit