Install

composer require maildeno/maildeno

Requires PHP 8.1+ with ext-curl and ext-json, plus symfony/process (^6.4 || ^7.0) — installed automatically as a real dependency, not optional. It’s needed for every render, since rendering shells out to the bundled maildeno-engine binary.

Configure the client

use Maildeno\MaildenoClient;

$client = new MaildenoClient([
    // Required — obtain from Dashboard → API Keys → Create Key
    'apiKey' => getenv('MAILDENO_API_KEY'),
]);

Configuration options

Option Type Default Description

apiKey

string

Required. Your Maildeno API key.

cache

array

memory

Caching strategy and tuning (type, path, ttl, maxEntries). Omit for memory caching with defaults. See Caching.

enginePath

string

auto-detected

Exact path to the maildeno-engine binary, overriding auto-detection. For a non-standard binary location, or to point the client at a stub binary in tests.

Requests to the Maildeno API do use a configurable timeout, but the exact constructor key isn’t confirmed in the source material this page was generated from. Check MaildenoClient’s constructor in your installed copy — if it’s a `timeout key, let me know and I’ll add a row here.

Client lifecycle

MaildenoClient holds its config, its resolved cache, and — after the first render — the resolved path to the maildeno-engine binary. Construct it once and reuse it rather than building a new instance per render:

// Bootstrap once — e.g. in a service container or a shared include
$maildeno = new MaildenoClient(['apiKey' => getenv('MAILDENO_API_KEY')]);

function sendWelcomeEmail(MaildenoClient $maildeno, string $name, string $to): void
{
    $html = $maildeno->renderHtml('template-id', [
        'merge_tags' => ['text' => ['name' => $name]],
    ]);
    // ... send $html via your mail transport
}

Whether that instance actually stays reused across requests depends on your runtime. See Environments & Frameworks for how this plays out under classic php-fpm versus Octane/Swoole-style long-running workers.

Getting the native binaries

The package bundles a maildeno-engine binary per platform under bin/<platform>/:

bin/
├── windows-x64/engine.exe
├── linux-x64/engine     (musl, statically linked — runs on glibc and Alpine)
├── linux-arm64/engine   (musl, statically linked)
├── macos-x64/engine
└── macos-arm64/engine   (ad-hoc code-signed — codesign -s -)

NativeEngine::locate() resolves the right one for the current OS/architecture automatically the first time you render — nothing to configure for the platforms above. If you need a binary for a platform that isn’t bundled, or you’re building the package from source, see the maildeno-engine-cli project’s CI build matrix for how these are produced, and place the result where NativeEngine::locate() expects it (or point enginePath at it directly).

No Composer

The package ships a PSR-4 autoloader for Maildeno* that doesn’t need Composer *for that*:

require 'path/to/maildeno-php/autoload.php';

Rendering still needs symfony/process to be autoloadable — it’s a real dependency, not optional — so you’d need to source that separately too. Composer is the straightforward path; see the docblock in autoload.php if you have a reason to avoid it.