Package Exports
- @pearl-framework/mail
Readme
@pearl-framework/mail
Mailable classes and multi-transport email sending for Pearl.js.
Installation
npm install @pearl-framework/mail @pearl-framework/core nodemailerRequires nodemailer v7+. Types are bundled —
@types/nodemaileris not needed.
Define a Mailable
A Mailable is a class that encapsulates a single email. Build it with a fluent API:
import { Mailable } from '@pearl-framework/mail'
export class WelcomeEmail extends Mailable {
constructor(private readonly user: User) { super() }
build(): this {
return this
.sendTo(this.user.email)
.from({ name: 'Pearl App', address: 'hi@pearl.dev' })
.subject(`Welcome to Pearl, ${this.user.name}!`)
.html(`
<h1>Hi ${this.user.name}, welcome aboard!</h1>
<p>We're thrilled to have you.</p>
<a href="https://yourapp.com/dashboard">Get started →</a>
`)
.text(`Hi ${this.user.name}, welcome aboard! Visit https://yourapp.com/dashboard`)
}
}Send Mail
const mailer = app.make(Mailer)
await mailer.send(new WelcomeEmail(user))
await mailer.sendBulk([new InvoiceEmail(u1), new InvoiceEmail(u2)])Advanced Mailables
Multiple recipients
build(): this {
return this
.sendTo('alice@example.com', 'bob@example.com')
.cc({ name: 'Manager', address: 'manager@example.com' })
.bcc('audit@internal.com')
.replyTo('support@example.com')
.subject('Team announcement')
.html('<p>Hello everyone!</p>')
}Attachments
build(): this {
return this
.sendTo(this.user.email)
.subject('Your invoice')
.html('<p>Please find your invoice attached.</p>')
.attach({
filename: 'invoice-2024-01.pdf',
path: `/tmp/invoices/${this.invoiceId}.pdf`,
contentType: 'application/pdf',
})
}Async build
build() can also be async — useful for fetching data inside the mailable:
async build(): Promise<this> {
const stats = await fetchUserStats(this.user.id)
return this
.sendTo(this.user.email)
.subject('Your weekly report')
.html(renderStatsTemplate(stats))
}MailServiceProvider
import { MailServiceProvider } from '@pearl-framework/mail'
import type { MailDriver } from '@pearl-framework/mail'
export class AppMailServiceProvider extends MailServiceProvider {
protected config = {
driver: (process.env.MAIL_DRIVER ?? 'log') as MailDriver,
from: {
name: 'Pearl App',
address: process.env.MAIL_FROM!,
},
smtp: {
host: process.env.MAIL_HOST!,
port: Number(process.env.MAIL_PORT ?? 587),
secure: false,
auth: {
user: process.env.MAIL_USER!,
pass: process.env.MAIL_PASS!,
},
},
}
}
app.register(AppMailServiceProvider)Transports
| Transport | Driver value | Description |
|---|---|---|
SmtpTransport |
'smtp' |
Send via any SMTP provider (Mailgun, Postmark, Resend, etc.) |
SesTransport |
'ses' |
Send via AWS SES (@aws-sdk/client-ses required) |
LogTransport |
'log' |
Print email details to the console instead of sending |
ArrayTransport |
'array' |
Capture sent mail in memory — for testing |
Switching by environment
// .env
MAIL_DRIVER=log # development
MAIL_DRIVER=smtp # productionThe LogTransport prints full email details to the console so you can verify emails look correct during development without needing an SMTP server.
Testing with ArrayTransport
import { ArrayTransport, Mailer } from '@pearl-framework/mail'
const transport = new ArrayTransport()
const mailer = new Mailer(transport)
await mailer.send(new WelcomeEmail(user))
const sent = transport.last()
assert.equal(sent?.subject, `Welcome to Pearl, ${user.name}!`)
assert.equal(transport.sent.length, 1)
transport.clear() // reset between testsAPI Reference
Mailable
| Method | Description |
|---|---|
sendTo(...addresses) |
Set recipient(s) — accepts strings or { name, address } objects |
from(address) |
Set the sender |
cc(...addresses) |
Add CC recipients |
bcc(...addresses) |
Add BCC recipients |
replyTo(address) |
Set the reply-to address |
subject(value) |
Set the subject line |
html(content) |
Set the HTML body |
text(content) |
Set the plain-text body |
attach(attachment) |
Add an attachment |
build() |
Required. Called by mailer.send() to build the mail — sync or async |
Mailer
| Method | Description |
|---|---|
send(mailable) |
Build and send a single mailable |
sendBulk(mailables[]) |
Build and send multiple mailables |
ArrayTransport
| Property / Method | Description |
|---|---|
sent |
Array of all BuiltMail objects that have been sent |
last() |
Returns the most recently sent mail, or undefined |
clear() |
Resets the sent array |