Lockness Mail
Lockness Mail
Email sending library with fluent API and multiple driver support.
Overview
@lockness/mail provides an expressive email builder with support for SMTP, Resend, Console (dev), and Memory (testing) drivers. Full email features including CC, BCC, Reply-To, attachments, and JSX templates.
Installation
typescript
import { configureMail, mail } from '@lockness/mail'
Configuration
typescript
configureMail({
driver: 'smtp', // 'smtp' | 'resend' | 'console' | 'memory'
from: { email: 'noreply@example.com', name: 'My App' },
smtp: {
host: 'smtp.example.com',
port: 587,
auth: { user: 'username', pass: 'password' },
},
resend: {
apiKey: 'your-api-key',
},
})
Basic Usage
Simple Email
typescript
await mail()
.to('user@example.com')
.subject('Welcome!')
.html('<h1>Hello World!</h1>')
.send()
Full Example
typescript
await mail()
.from('sender@example.com', 'Sender Name')
.to('recipient@example.com')
.cc('cc@example.com')
.bcc('bcc@example.com')
.replyTo('reply@example.com')
.subject('Test Email')
.text('Plain text version')
.html('<strong>HTML version</strong>')
.attach('file.txt', 'File content')
.send()
With JSX Templates
typescript
const EmailTemplate = ({ name }: { name: string }) => (
<html>
<body>
<h1>Welcome, {name}!</h1>
<p>Thanks for joining our service.</p>
</body>
</html>
)
await mail()
.to('user@example.com')
.subject('Welcome!')
.view(<EmailTemplate name='John' />)
.send()
Drivers
Console Driver (Development)
Prints emails to console instead of sending them.
typescript
configureMail({ driver: 'console' })
Memory Driver (Testing)
Stores emails in memory for testing.
typescript
import { MemoryMailDriver } from '@lockness/mail'
configureMail({ driver: 'memory' })
// Send email
await mail().to('test@example.com').subject('Test').send()
// Get sent emails
const emails = MemoryMailDriver.getSentEmails()
const lastEmail = MemoryMailDriver.getLastEmail()
// Clear
MemoryMailDriver.clear()
SMTP Driver
typescript
configureMail({
driver: 'smtp',
smtp: {
host: 'smtp.gmail.com',
port: 587,
auth: {
user: 'your-email@gmail.com',
pass: 'your-password',
},
},
})
Resend Driver
typescript
configureMail({
driver: 'resend',
resend: {
apiKey: Deno.env.get('RESEND_API_KEY'),
},
})
API Reference
Mail Builder Methods
from(email, name?)- Set senderto(email, name?)- Set recipient (can call multiple times)cc(email, name?)- Add CC recipientbcc(email, name?)- Add BCC recipientreplyTo(email)- Set reply-to addresssubject(subject)- Set email subjecttext(content)- Set plain text contenthtml(content)- Set HTML contentview(jsx)- Set JSX template contentattach(filename, content)- Add attachmentsend()- Send the email
Common Use Cases
Password Reset Email
typescript
import { mail } from '@lockness/mail'
async function sendPasswordReset(user: User, resetToken: string) {
const resetUrl = `https://example.com/reset-password?token=${resetToken}`
await mail()
.to(user.email, user.name)
.subject('Reset Your Password')
.html(`
<h1>Password Reset Request</h1>
<p>Click the link below to reset your password:</p>
<a href="${resetUrl}">Reset Password</a>
<p>This link expires in 1 hour.</p>
`)
.send()
}
Welcome Email with Template
typescript
const WelcomeEmail = (
{ name, verifyUrl }: { name: string; verifyUrl: string },
) => (
<html>
<body style='font-family: Arial, sans-serif;'>
<h1>Welcome, {name}!</h1>
<p>Thanks for signing up. Please verify your email:</p>
<a
href={verifyUrl}
style='background: #007bff; color: white; padding: 10px 20px; text-decoration: none;'
>
Verify Email
</a>
</body>
</html>
)
await mail()
.to(user.email, user.name)
.subject('Welcome to Our App')
.view(<WelcomeEmail name={user.name} verifyUrl={verifyUrl} />)
.send()
Email with Attachments
typescript
await mail()
.to('user@example.com')
.subject('Invoice')
.html('<p>Your invoice is attached.</p>')
.attach('invoice.pdf', pdfBytes)
.attach('receipt.txt', 'Receipt content')
.send()
Testing Emails
typescript
import { MemoryMailDriver } from '@lockness/mail'
// Setup
configureMail({ driver: 'memory' })
// Your code sends email
await sendWelcomeEmail(user)
// Assert in tests
const emails = MemoryMailDriver.getSentEmails()
assertEquals(emails.length, 1)
assertEquals(emails[0].to[0].email, 'user@example.com')
assertEquals(emails[0].subject, 'Welcome!')
// Cleanup
MemoryMailDriver.clear()
Best Practices
- Use Console driver in development to avoid accidental emails
- Use Memory driver in tests with MemoryMailDriver.clear() in afterEach
- Set default
fromaddress in configuration - Use JSX templates for complex emails with consistent styling
- Always include both text and html content for best compatibility
- Store SMTP credentials and API keys in environment variables
- For bulk emails, consider implementing rate limiting
- Use proper error handling around mail.send() calls
Environment Variables
bash
# .env
MAIL_DRIVER=smtp
MAIL_FROM_EMAIL=noreply@example.com
MAIL_FROM_NAME="My App"
# SMTP
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
# Resend
RESEND_API_KEY=re_123456789