PHPackages                             pulli/emate - 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. pulli/emate

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

pulli/emate
===========

Wrapper for MailMate's emate CLI

v2.1.2(2mo ago)0548↓38.5%MITPHPPHP ^8.2CI passing

Since Jan 8Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/the-pulli/emate)[ Packagist](https://packagist.org/packages/pulli/emate)[ Docs](https://github.com/the-pulli/emate)[ GitHub Sponsors](https://github.com/the-pulli)[ RSS](/packages/pulli-emate/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (10)Versions (13)Used By (0)

Wrapper for MailMate's emate CLI
================================

[](#wrapper-for-mailmates-emate-cli)

[![Latest Version on Packagist](https://camo.githubusercontent.com/e108a5513823265c942fe7c4eb44cc2d9de23ca73c087a15dca6894c99dbcd34/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f70756c6c692f656d6174652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/pulli/emate)[![Tests](https://camo.githubusercontent.com/432a26be058993c2ac0fc09184383090e566267f2713b9f653d890e2d76d3c13/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7468652d70756c6c692f656d6174652f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/the-pulli/emate/actions/workflows/run-tests.yml)[![Total Downloads](https://camo.githubusercontent.com/7de303895b05f23806302b86066ac9e86638c1d8ec5e9482dc309481265f83d4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f70756c6c692f656d6174652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/pulli/emate)

A PHP wrapper for [MailMate's](https://freron.com) `emate` CLI tool. Provides a fluent, object-oriented interface to compose and send emails via MailMate's command-line binary.

Features
--------

[](#features)

- Fluent builder pattern via static factory method
- Support for TO, CC, BCC, and Reply-To recipients
- File attachments
- Markdown body formatting
- OpenPGP and S/MIME encryption and signing
- Send-now mode for immediate delivery
- Flexible address formats: plain strings, `"Name" ` format, arrays, and Symfony `Address` objects
- Shell-safe command generation with proper argument escaping

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

[](#installation)

```
composer require pulli/emate
```

Symlink Setup
-------------

[](#symlink-setup)

MailMate ships the `emate` binary inside its application bundle. Create a symlink to make it available in your `$HOME/bin`:

```
use Pulli\Emate\Emate;

// Creates symlink at $HOME/bin/emate (default)
Emate::symlink();

// Or specify a custom directory
Emate::symlink('/usr/local/bin');
```

Usage
-----

[](#usage)

### Basic Email

[](#basic-email)

```
use Pulli\Emate\Emate;

Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Hello',
    'body' => 'This is the email body.',
])->mail();
```

### With Named Recipients

[](#with-named-recipients)

```
Emate::from([
    'to' => 'John Doe ',
    'from' => 'sender@example.com',
    'subject' => 'Hello John',
    'body' => 'Hi there!',
])->mail();
```

### Multiple Recipients

[](#multiple-recipients)

```
// As an array
Emate::from([
    'to' => ['alice@example.com', 'Bob '],
    'from' => 'sender@example.com',
    'subject' => 'Group message',
    'body' => 'Hello everyone!',
])->mail();

// As a newline-separated string
Emate::from([
    'to' => "alice@example.com\nBob ",
    'from' => 'sender@example.com',
    'subject' => 'Group message',
    'body' => 'Hello everyone!',
])->mail();
```

### CC and BCC

[](#cc-and-bcc)

```
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'cc' => ['manager@example.com', 'team@example.com'],
    'bcc' => 'archive@example.com',
    'subject' => 'Update',
    'body' => 'Please see the update.',
])->mail();
```

### Reply-To

[](#reply-to)

```
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'reply_to' => 'replies@example.com',
    'subject' => 'Hello',
    'body' => 'Please reply to the other address.',
])->mail();
```

### Symfony Address Objects

[](#symfony-address-objects)

```
use Symfony\Component\Mime\Address;

Emate::from([
    'to' => new Address('recipient@example.com', 'Recipient'),
    'from' => new Address('sender@example.com', 'Sender'),
    'reply_to' => new Address('replies@example.com', 'Reply Handler'),
    'subject' => 'Hello',
    'body' => 'Using Address objects.',
])->mail();
```

### File Attachments

[](#file-attachments)

```
// As an array
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Files attached',
    'body' => 'See attached.',
    'files' => ['/path/to/report.pdf', '/path/to/data.csv'],
])->mail();

// As a newline-separated string
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'File attached',
    'body' => 'See attached.',
    'files' => '/path/to/report.pdf',
])->mail();
```

### Markdown Body

[](#markdown-body)

```
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Formatted email',
    'body' => "# Heading\n\nThis is **bold** and this is *italic*.",
    'markdown' => true,
])->mail();
```

### Encryption and Signing

[](#encryption-and-signing)

```
use Pulli\Emate\EncryptionMode;

// Encrypt with OpenPGP (default)
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Secret',
    'body' => 'Encrypted content.',
    'encrypt' => true,
])->mail();

// Sign with OpenPGP (default)
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Signed',
    'body' => 'Verified content.',
    'sign' => true,
])->mail();

// Encrypt and sign with OpenPGP (default)
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Secure',
    'body' => 'Encrypted and signed.',
    'encrypt' => true,
    'sign' => true,
])->mail();

// Sign with S/MIME
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Signed',
    'body' => 'Verified content.',
    'sign' => true,
    'encryption_mode' => 'smime',
])->mail();

// Encrypt and sign with S/MIME, using the enum directly
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Secure',
    'body' => 'Encrypted and signed.',
    'encrypt' => true,
    'sign' => true,
    'encryption_mode' => EncryptionMode::SMIME,
])->mail();
```

### Signature

[](#signature)

```
// Set a text signature
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Hello',
    'body' => 'Email body.',
    'signature' => 'Best regards, PuLLi',
])->mail();

// Reference an existing signature by UUID
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Hello',
    'body' => 'Email body.',
    'signature' => 'uuid:12345-abcde',
])->mail();
```

### Custom Headers

[](#custom-headers)

```
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Hello',
    'body' => 'Email body.',
    'headers' => ['X-Priority: 1', 'X-Mailer: My App'],
])->mail();
```

### Send Immediately

[](#send-immediately)

```
Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Urgent',
    'body' => 'This sends immediately without queuing in drafts.',
    'send_now' => true,
])->mail();
```

### Fluent Builder

[](#fluent-builder)

Use `Emate::compose()` for a fluent builder API instead of passing an options array:

```
use Pulli\Emate\Emate;
use Pulli\Emate\EncryptionMode;

// Basic email
Emate::compose()
    ->to('recipient@example.com')
    ->sender('sender@example.com')
    ->subject('Hello')
    ->body('This is the email body.')
    ->mail();

// With all options
Emate::compose()
    ->to(['alice@example.com', 'Bob '])
    ->sender('sender@example.com')
    ->cc('manager@example.com')
    ->bcc('archive@example.com')
    ->replyTo('replies@example.com')
    ->subject('Full example')
    ->body('# Heading\n\nMarkdown body.')
    ->files(['/path/to/report.pdf'])
    ->markdown()
    ->encrypt()
    ->sign()
    ->sendNow()
    ->encryptionMode(EncryptionMode::SMIME)
    ->signature('Best regards')
    ->header('X-Priority', '1')
    ->mail();
```

### Debugging

[](#debugging)

Use `debug()` instead of `mail()` to inspect the generated shell command without executing it:

```
$command = Emate::from([
    'to' => 'recipient@example.com',
    'from' => 'sender@example.com',
    'subject' => 'Test',
    'body' => 'Hello',
])->debug();

echo $command;
// echo 'Hello' | $HOME/bin/emate mailto --to 'recipient@example.com' --subject 'Test' --from 'sender@example.com' --noencrypt --nosign
```

Options Reference
-----------------

[](#options-reference)

OptionTypeDefaultDescription`body``string``''`Email body text`to``string|array|Address``[]`Recipient(s)`from``string|Address``''`Sender address`subject``string``''`Email subject`cc``string|array|Address``[]`CC recipient(s)`bcc``string|array|Address``[]`BCC recipient(s)`reply_to``string|Address``''`Reply-to address`files``string|array``[]`File path(s) to attach`markdown``bool|string``false`Render body as Markdown (`true`, `'yes'`, `'true'`)`encrypt``bool|string``false`Encrypt the message (`true`, `'yes'`, `'true'`)`sign``bool|string``false`Sign the message (`true`, `'yes'`, `'true'`)`send_now``bool|string``false`Send immediately (`true`, `'yes'`, `'true'`)`encryption_mode``string|EncryptionMode``'openpgp'`Encryption mode: `'openpgp'` or `'smime'``signature``string``''`Signature text or `'uuid:'` to reference an existing signature`headers``array``[]`Arbitrary headers formatted as `'Name: Value'` stringsTesting
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [PuLLi](https://github.com/the-pulli)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance86

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 71.4% 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 ~39 days

Recently: every ~24 days

Total

12

Last Release

70d ago

Major Versions

v1.1.0 → v2.0.02026-01-23

PHP version history (2 changes)v1.0.0PHP ^8.3

v1.0.1PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/c14e16040b5b84e5c91af8c7a39480567d951bfc27673f97d9c75480dbe20b5e?d=identicon)[pulli](/maintainers/pulli)

---

Top Contributors

[![the-pulli](https://avatars.githubusercontent.com/u/112799107?v=4)](https://github.com/the-pulli "the-pulli (35 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (9 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (5 commits)")

---

Tags

pulliematemailmate

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/pulli-emate/health.svg)

```
[![Health](https://phpackages.com/badges/pulli-emate/health.svg)](https://phpackages.com/packages/pulli-emate)
```

###  Alternatives

[symfony/mailer

Helps sending emails

1.6k368.1M955](/packages/symfony-mailer)[directorytree/imapengine

A fully-featured IMAP library -- without the PHP extension

531175.4k4](/packages/directorytree-imapengine)[dotdigital/dotdigital-magento2-extension

Dotdigital for Magento 2

50374.2k18](/packages/dotdigital-dotdigital-magento2-extension)[railsware/mailtrap-php

The Mailtrap SDK provides methods for all API functions.

56770.5k](/packages/railsware-mailtrap-php)[terminal42/notification_center

Notification Center extension for Contao Open Source CMS

68396.6k78](/packages/terminal42-notification-center)[creagia/laravel-web-mailer

Laravel Web Mailer

6923.5k](/packages/creagia-laravel-web-mailer)

PHPackages © 2026

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