PHPackages                             vancil/flint-mail - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Mail &amp; Notifications](/categories/mail)
4. /
5. vancil/flint-mail

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

vancil/flint-mail
=================

Full-featured mail package for Flint — Mailables, queueing, and HTTP API drivers

v1.0.1(1mo ago)02MITPHPPHP &gt;=8.1CI passing

Since May 31Pushed 1mo agoCompare

[ Source](https://github.com/Vancil/flint-mail)[ Packagist](https://packagist.org/packages/vancil/flint-mail)[ RSS](/packages/vancil-flint-mail/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (2)Dependencies (2)Versions (8)Used By (0)

flint-mail
==========

[](#flint-mail)

 [![Tests](https://camo.githubusercontent.com/463a8787c6d57f17bd92112d7025bf1a94fa13c4474a5a4fcc1637f45d47551e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f56616e63696c2f666c696e742d6d61696c2f63692e796d6c3f6c6162656c3d7465737473)](https://github.com/Vancil/flint-mail/actions/workflows/ci.yml) [![Total Downloads](https://camo.githubusercontent.com/6ae8b43ca37ebf034aa15deb19280bce60bce7c75da84005f87140ec977a7d45/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f76616e63696c2f666c696e742d6d61696c)](https://packagist.org/packages/vancil/flint-mail) [![Latest Version on Packagist](https://camo.githubusercontent.com/1f180b8cd75b786525491917b2875ade8aa3639f9b313377d644e3902cef2a6d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f76616e63696c2f666c696e742d6d61696c)](https://packagist.org/packages/vancil/flint-mail) [![License](https://camo.githubusercontent.com/b8cadaa967891081f8f165695470689986c028821dd8a040132f6e661795dc0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c7565)](https://github.com/Vancil/flint-mail/blob/master/LICENSE)

Full-featured mail package for the [Flint framework](https://github.com/Vancil/flint). Mailable classes, async queueing, CC/BCC/attachments, and six sending drivers — all with zero new dependencies beyond Flint itself.

---

Installation
------------

[](#installation)

```
composer require vancil/flint-mail
```

Register the package in `config/app.php`:

```
'packages' => [
    \Vancil\FlintMail\FlintMail::class,
],
```

Run the installer to publish the config and migration:

```
php flint mail:install
php flint migrate
```

---

Mailable Classes
----------------

[](#mailable-classes)

Create a Mailable with the CLI:

```
php flint make:mail WelcomeEmail
```

This creates `app/Mail/WelcomeEmail.php`. Define your email inside `build()`:

```
namespace App\Mail;

use Vancil\FlintMail\Mailable;

class WelcomeEmail extends Mailable
{
    public function __construct(private User $user) {}

    public function build(): void
    {
        $this->to($this->user->email, $this->user->name)
             ->subject('Welcome to ' . config('app.name'))
             ->view('emails.welcome', ['user' => $this->user]);
    }
}
```

### Sending

[](#sending)

```
// Synchronous — sends immediately
(new WelcomeEmail($user))->send();

// Queued — dispatched to Flint's queue worker
(new WelcomeEmail($user))->queue();
(new WelcomeEmail($user))->queue('emails'); // named queue
```

### All Builder Methods

[](#all-builder-methods)

```
$this->to('user@example.com', 'User')         // recipient
     ->from('sender@example.com', 'Sender')   // override default from
     ->replyTo('replies@example.com')
     ->subject('Hello')
     ->cc('manager@example.com', 'Manager')
     ->cc('another@example.com')
     ->bcc('audit@example.com')
     ->html('Hello world')       // raw HTML body
     ->text('Hello world')                     // plain text fallback
     ->view('emails.welcome', ['user' => $u]) // Spark template as HTML
     ->attach('/path/to/file.pdf', 'Invoice.pdf', 'application/pdf');
```

---

Fluent API (without Mailables)
------------------------------

[](#fluent-api-without-mailables)

You can also send ad-hoc emails via the injected `Mailer`:

```
use Vancil\FlintMail\Mailer;

class NotificationController
{
    public function __construct(private readonly Mailer $mailer) {}

    public function notify(Request $request): Response
    {
        $this->mailer
            ->to('user@example.com', 'User')
            ->subject('New notification')
            ->html('You have a new message.')
            ->cc('admin@example.com')
            ->send();

        // Or queue it:
        $this->mailer
            ->to('user@example.com')
            ->subject('Report')
            ->attach('/tmp/report.pdf', 'Monthly Report.pdf')
            ->queue('reports');

        return Response::redirect('/');
    }
}
```

---

Queued Mail
-----------

[](#queued-mail)

When `queue()` is called, flint-mail:

1. Renders the email body immediately
2. Persists a `QueuedMail` record to the database with `status = pending`
3. Dispatches a `SendMailJob` to Flint's queue system

Start the queue worker to process queued mail:

```
php flint queue:work
php flint queue:work --queue=emails   # process a named queue
```

The `queued_mails` table tracks each email's lifecycle:

ColumnDescription`status``pending` → `processing` → `sent` or `failed``attempts`How many send attempts have been made`error`Last error message if `failed``sent_at`Timestamp when successfully deliveredFailed jobs are retried up to 3 times (60 second delay between attempts).

---

Drivers
-------

[](#drivers)

Set `MAIL_DRIVER` in `.env` to choose your sending backend.

### Log (default)

[](#log-default)

Writes emails to `storage/logs/mail.log`. Use this locally.

```
MAIL_DRIVER=log
```

### SMTP

[](#smtp)

Raw socket SMTP — works with any SMTP server (Gmail, Mailgun SMTP, SES SMTP, etc.).

```
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=587
MAIL_USERNAME=your-username
MAIL_PASSWORD=your-password
MAIL_ENCRYPTION=tls
```

### Mailgun

[](#mailgun)

```
MAIL_DRIVER=mailgun
MAILGUN_SECRET=key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
MAILGUN_DOMAIN=mg.yourdomain.com
MAILGUN_REGION=us    # or 'eu' for EU region
```

### Postmark

[](#postmark)

```
MAIL_DRIVER=postmark
POSTMARK_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

### Amazon SES

[](#amazon-ses)

```
MAIL_DRIVER=ses
AWS_ACCESS_KEY_ID=AKIAXXXXXXXXXXXXXXXX
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
AWS_DEFAULT_REGION=us-east-1
```

SES requests are signed with AWS Signature Version 4, implemented inline with no external SDK.

### SendGrid

[](#sendgrid)

```
MAIL_DRIVER=sendgrid
SENDGRID_API_KEY=SG.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

---

Configuration
-------------

[](#configuration)

`config/mail.php` (published by `php flint mail:install`):

```
return [
    'driver' => env('MAIL_DRIVER', 'log'),

    'from' => [
        'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
        'name'    => env('MAIL_FROM_NAME', 'Flint'),
    ],

    'mailgun'  => ['key' => env('MAILGUN_SECRET'), 'domain' => env('MAILGUN_DOMAIN'), 'region' => 'us'],
    'postmark' => ['token' => env('POSTMARK_TOKEN')],
    'ses'      => ['key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1')],
    'sendgrid' => ['key' => env('SENDGRID_API_KEY')],
];
```

---

Email Templates
---------------

[](#email-templates)

Email HTML bodies can be written as [Spark](https://github.com/Vancil/flint) templates:

`resources/views/emails/welcome.spark.php`:

```
>

    Welcome, {{ $user->name }}!
    Thanks for joining. Your account is ready.

```

Then reference it in your Mailable:

```
$this->view('emails.welcome', ['user' => $user]);
```

---

Writing a Custom Driver
-----------------------

[](#writing-a-custom-driver)

Implement `Vancil\FlintMail\Drivers\DriverInterface`:

```
namespace App\Mail\Drivers;

use Vancil\FlintMail\Drivers\DriverInterface;
use Vancil\FlintMail\MailMessage;

class ResendDriver implements DriverInterface
{
    public function send(MailMessage $message): void
    {
        // $message->to, ->toName, ->subject, ->htmlBody, ->textBody
        // ->from, ->fromName, ->replyTo, ->cc, ->bcc, ->attachments
    }
}
```

Register it in `FlintMail::register()` by extending the package or binding it in your `Application::boot()`.

---

License
-------

[](#license)

MIT — [Vancil](https://github.com/Vancil)

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance89

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

55d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/57faf02cb728789f5bb1242a73090ac1e9040ca9c10baf655e3a7e72d555d9ad?d=identicon)[SimpleVerify](/maintainers/SimpleVerify)

---

Top Contributors

[![danrovito](https://avatars.githubusercontent.com/u/8322674?v=4)](https://github.com/danrovito "danrovito (14 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/vancil-flint-mail/health.svg)

```
[![Health](https://phpackages.com/badges/vancil-flint-mail/health.svg)](https://phpackages.com/packages/vancil-flint-mail)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
