Background Processing

Email System

Production-ready email support with multiple adapters (Nodemailer, SendGrid, AWS SES, Resend). Template rendering, queue integration, and zero forced dependencies.

Overview

Without proper email systems, you're manually integrating different providers, managing templates, and handling async sending. With MoroJS, you get all of that automatically.

Traditional email setup requires different libraries and APIs for each provider. We give you one consistent API.

Send emails with one call
1import { createApp } from '@morojs/moro';
2
3const app = await createApp();
4
5// Configure email
6app.mailInit({
7  adapter: 'nodemailer',
8  from: { name: 'My App', email: '[email protected]' },
9  connection: {
10    host: 'smtp.gmail.com',
11    port: 587,
12    auth: {
13      user: process.env.EMAIL_USER,
14      pass: process.env.EMAIL_PASSWORD
15    }
16  }
17});
18
19// Send email
20await app.sendMail({
21  to: '[email protected]',
22  subject: 'Welcome',
23  template: 'welcome',
24  data: { name: 'John' }
25});

Without Email System

  • Different APIs for each provider
  • Manual template management
  • No built-in queue integration
  • Complex provider switching

With MoroJS

  • Same API across all providers
  • Built-in template rendering
  • Automatic queue integration
  • Easy provider switching
Same API, different providers
1// Nodemailer (SMTP)
2app.mailInit({ adapter: 'nodemailer', ... });
3
4// SendGrid
5app.mailInit({ adapter: 'sendgrid', ... });
6
7// AWS SES
8app.mailInit({ adapter: 'ses', ... });
9
10// Resend
11app.mailInit({ adapter: 'resend', ... });
12
13// All use the same API
14await app.sendMail({
15  to: '[email protected]',
16  subject: 'Welcome',
17  template: 'welcome',
18  data: { name: 'John' }
19});

Flexible

Choose Nodemailer, SendGrid, SES, or Resend. Same API.

Templates

Built-in template rendering with Moro, Handlebars, or EJS.

Queue Ready

Automatic queue integration for async sending.

How It Works

MoroJS provides a unified email API that works with multiple providers. You configure your chosen adapter, send emails with templates, and optionally integrate with queues for async sending. The system handles provider-specific details automatically.

Quick Start

Installation
1# Install the adapter you need (all optional)
2npm install nodemailer          # For SMTP
3npm install @sendgrid/mail      # For SendGrid
4npm install @aws-sdk/client-ses # For AWS SES
5npm install resend              # For Resend
Basic Configuration
1import { createApp } from '@morojs/moro';
2
3const app = await createApp();
4
5// Configure email - synchronous, no await needed!
6app.mailInit({
7  adapter: 'nodemailer',
8  from: {
9    name: 'My App',
10    email: '[email protected]'
11  },
12  connection: {
13    host: 'smtp.gmail.com',
14    port: 587,
15    secure: false,
16    auth: {
17      user: process.env.EMAIL_USER,
18      pass: process.env.EMAIL_PASSWORD
19    }
20  },
21  templates: {
22    path: './emails',
23    engine: 'moro', // or 'handlebars', 'ejs'
24    cache: true
25  },
26  queue: {
27    enabled: true,
28    name: 'emails'
29  }
30});
Sending Emails
1// Simple email
2await app.sendMail({
3  to: '[email protected]',
4  subject: 'Welcome',
5  text: 'Welcome to our app!',
6  html: '<h1>Welcome to our app!</h1>'
7});
8
9// With template
10await app.sendMail({
11  to: '[email protected]',
12  subject: 'Password Reset',
13  template: 'password-reset',
14  data: {
15    name: 'John',
16    resetUrl: 'https://myapp.com/reset/token123'
17  }
18});
19
20// With attachments
21await app.sendMail({
22  to: '[email protected]',
23  subject: 'Invoice',
24  template: 'invoice',
25  data: { invoice },
26  attachments: [
27    {
28      filename: 'invoice.pdf',
29      content: pdfBuffer
30    }
31  ]
32});
33
34// Batch emails
35await app.sendBulkMail([
36  { to: '[email protected]', subject: 'Hello', text: 'Hi!' },
37  { to: '[email protected]', subject: 'Hello', text: 'Hi!' }
38]);

Template System

Template Example
1// emails/welcome.html
2<!DOCTYPE html>
3<html>
4<head>
5  <style>
6    body { font-family: Arial, sans-serif; }
7    .button { background: #007bff; color: white; padding: 10px 20px; }
8  </style>
9</head>
10<body>
11  <h1>Welcome {{name}}!</h1>
12  <p>Thanks for joining {{appName}}. We're excited to have you.</p>
13
14  {{#if verifyUrl}}
15    <a href="{{verifyUrl}}" class="button">Verify Your Email</a>
16  {{/if}}
17
18  <p>Best regards,<br>The {{appName}} Team</p>
19</body>
20</html>
Using Templates
1// Use template
2await app.sendMail({
3  to: user.email,
4  template: 'welcome',
5  data: {
6    name: user.name,
7    appName: 'My App',
8    isPremium: user.plan === 'premium',
9    verifyUrl: generateVerifyUrl(user)
10  }
11});

Email Adapters

Nodemailer (SMTP)
1app.mailInit({
2  adapter: 'nodemailer',
3  connection: {
4    host: 'smtp.gmail.com',
5    port: 587,
6    secure: false,
7    auth: {
8      user: process.env.EMAIL_USER,
9      pass: process.env.EMAIL_PASSWORD
10    }
11  }
12});
13
14// Works with any SMTP server
15// Gmail, Outlook, custom servers
16// OAuth2 authentication support
SendGrid
1app.mailInit({
2  adapter: 'sendgrid',
3  apiKey: process.env.SENDGRID_API_KEY,
4  from: {
5    name: 'My App',
6    email: '[email protected]'
7  }
8});
9
10// Features:
11// - Template management in SendGrid
12// - Click/open tracking
13// - Suppression list management
14// - Webhook integration
AWS SES
1app.mailInit({
2  adapter: 'ses',
3  region: 'us-east-1',
4  credentials: {
5    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
6    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
7  }
8});
9
10// Features:
11// - Configuration sets
12// - Bounce/complaint handling
13// - Email verification
14// - High volume sending
Resend
1app.mailInit({
2  adapter: 'resend',
3  apiKey: process.env.RESEND_API_KEY,
4  from: {
5    name: 'My App',
6    email: '[email protected]'
7  }
8});
9
10// Features:
11// - Modern REST API
12// - Simple authentication
13// - Domain verification
14// - Batch sending
Console Adapter (Testing)
1app.mailInit({
2  adapter: 'console',
3  // Logs emails to console for development/testing
4  // No external dependencies required
5});
6
7// Perfect for:
8// - Development
9// - Testing
10// - CI/CD pipelines

Use Cases

User Registration
1app.post('/register')
2  .body(RegisterSchema)
3  .handler(async (req, res) => {
4    const user = await createUser(req.body);
5
6    // Send welcome email (queued)
7    await app.sendMail({
8      to: user.email,
9      template: 'welcome',
10      data: {
11        name: user.name,
12        verifyUrl: generateVerifyUrl(user)
13      }
14    });
15
16    return { success: true };
17  });
Password Reset
1app.post('/forgot-password')
2  .body(z.object({ email: z.string().email() }))
3  .handler(async (req, res) => {
4    const user = await findUser(req.body.email);
5    const token = generateResetToken(user);
6
7    await app.sendMail({
8      to: user.email,
9      template: 'password-reset',
10      data: {
11        name: user.name,
12        resetUrl: `https://myapp.com/reset/${token}`,
13        expiresIn: '1 hour'
14      }
15    });
16
17    return { success: true };
18  });
Transactional Emails
1// Order confirmation
2await app.sendMail({
3  to: order.customerEmail,
4  template: 'order-confirmation',
5  data: {
6    orderNumber: order.id,
7    items: order.items,
8    total: order.total,
9    trackingUrl: order.trackingUrl
10  },
11  attachments: [
12    {
13      filename: 'invoice.pdf',
14      content: await generateInvoice(order)
15    }
16  ]
17});

Queue Integration

Async Email Sending
1// Configure email with queue
2app.mailInit({
3  adapter: 'sendgrid',
4  apiKey: process.env.SENDGRID_API_KEY,
5  queue: {
6    enabled: true,
7    name: 'emails'
8  }
9});
10
11// Configure queue
12app.queueInit('emails', {
13  adapter: 'bull',
14  connection: {
15    host: 'localhost',
16    port: 6379
17  },
18  concurrency: 10
19});
20
21// Emails are automatically queued
22await app.sendMail({
23  to: '[email protected]',
24  template: 'welcome',
25  data: { name: 'John' }
26});
27
28// Returns immediately, email sent asynchronously

Features

Core Capabilities

  • Multiple provider support
  • Template rendering (Moro, Handlebars, EJS)
  • Attachment support
  • HTML and text emails
  • CC, BCC support
  • Queue integration for async sending

Supported Adapters

Nodemailer (Default)
SMTP, Gmail, custom mail servers
SendGrid
Templates, analytics, deliverability
AWS SES
High volume, cost-effective
Resend
Modern API, developer-friendly
Console (Built-in)
Development and testing

Next Steps