emailjs vs mailgun-js vs nodemailer vs sendgrid
JavaScript メール送信ライブラリの比較とアーキテクチャ選定
emailjsmailgun-jsnodemailersendgrid類似パッケージ:

JavaScript メール送信ライブラリの比較とアーキテクチャ選定

emailjsmailgun-jsnodemailersendgrid は、JavaScript アプリケーションからメールを送信するためのライブラリですが、通信プロトコルや動作環境、保守状況に大きな違いがあります。nodemailer は Node.js 環境で SMTP プロトコルを使用する標準的なライブラリです。emailjs も SMTP クライアントですが、ブラウザ環境での動作も技術的に可能です。一方、mailgun-jssendgrid は、それぞれ Mailgun と SendGrid というメール配信サービスの API を利用するためのライブラリですが、現在はより新しい公式パッケージへの移行が推奨されています。フロントエンド開発者がこれらを選ぶ際は、サーバー側で動作させるか、クライアント側で動作させるか、そしてセキュリティリスクをどう管理するかが重要な判断基準になります。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
emailjs02,208319 kB15ヶ月前MIT
mailgun-js0892-528年前MIT
nodemailer017,568549 kB06時間前MIT-0
sendgrid03,052-939年前MIT

JavaScript メール送信ライブラリ:実装と保守状況の深掘り

JavaScript でメール機能を実装する際、emailjsmailgun-jsnodemailersendgrid という 4 つのパッケージがよく候補に挙がります。しかし、これらは同じ「メール送信」でも、裏側の仕組みや適した場所が全く異なります。フロントエンドアーキテクトとして、これらを選定する際は「どこで動かすか(サーバーかブラウザか)」と「どう保守するか」の 2 点が最重要になります。ここでは、実装コードと保守状況を元に、技術的な違いを明確にします。

🛠️ インストールと初期設定

パッケージの導入方法は単純ですが、依存関係の管理において違いがあります。特に sendgridmailgun-js は、後述する通り古いパッケージであるため、インストール段階で将来の技術的負債を抱えるリスクがあります。

nodemailer Node.js プロジェクトで標準的に使用されます。SMTP サーバーの設定をオブジェクトで渡して初期化します。

npm install nodemailer
// Node.js
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
  host: 'smtp.example.com',
  port: 587,
  secure: false,
  auth: { user: 'user', pass: 'pass' }
});

emailjs SMTP クライアントとして動作します。ブラウザでも Node.js でも動作しますが、設定には SMTP 認証情報が必要です。

npm install emailjs
// Browser or Node.js
const emailjs = require("emailjs/email");
const server = emailjs.server.connect({
   user: "username",
   password: "password",
   host: "smtp.emailjs.com",
   ssl: true
});

mailgun-js Mailgun の API を使うためのラッパーです。API キーとドメインが必要です。

npm install mailgun-js
// Node.js
const mailgun = require('mailgun-js')({
  apiKey: 'key-yourapikey',
  domain: 'yourdomain.com'
});

sendgrid SendGrid の API を使うための古いラッパーです。API キーが必要です。

npm install sendgrid
// Node.js
const sendgrid = require('sendgrid')('YOUR_API_KEY');

📤 メール送信の実装比較

実際の送信コードを見ると、プロトコルの違い(SMTP か HTTP API か)がはっきりとわかります。SMTP はメールサーバーとの直接通信、API は配信サービス経由の通信です。

nodemailer SMTP プロトコルを使用します。sendMail メソッドで送信します。サーバー側での使用が前提です。

await transporter.sendMail({
  from: '"Me" <me@example.com>',
  to: 'recipient@example.com',
  subject: 'Hello',
  text: 'World'
});

emailjs これも SMTP プロトコルです。server.send メソッドを使用します。ブラウザで実行すると、認証情報がクライアント側に露出します。

server.send({
  text: "email body",
  from: "you@yourdomain.com",
  to: "someone@otherdomain.com",
  subject: "Test Email"
}, callback);

mailgun-js HTTP API を使用します。messages().send で送信します。サービス側の機能(追跡など)が使えます。

const data = {
  from: 'Excited User <me@samples.mailgun.org>',
  to: 'test@example.com',
  subject: 'Hello',
  text: 'Testing some Mailgun awesomness!'
};
mailgun.messages().send(data, function (err, body) { /*...*/ });

sendgrid HTTP API を使用します。send メソッドで送信します。ただし、この API は古いバージョンに基づいています。

const email = new sendgrid.Email({
  to: 'test@example.com',
  from: 'test@test.com',
  subject: 'Hello',
  text: 'World'
});
sendgrid.send(email, function(err, json) { /*...*/ });

⚠️ 保守状況とセキュリティリスク

これが最も重要な architectural decision(アーキテクチャの決定)ポイントです。フロントエンド開発者がクライアントサイドのコードにこれらのライブラリを直接含めることは、多くの場合セキュリティ上の問題を引き起こします。

nodemaileremailjs のリスク これらは SMTP 認証情報(ユーザー名とパスワード)を必要とします。これをフロントエンドのコードに書くと、誰でもあなたのメールサーバーにログインできるようになってしまいます。そのため、nodemailer は必ずサーバー側(Node.js バックエンド)で動かす必要があります。emailjs も同様ですが、サービス提供元の EmailJS 社が提供する @emailjs/browser という別の SDK があり、こちらは認証情報を隠蔽できる仕組みになっているため、フロントエンドから使うならこちらを選ぶべきです。

mailgun-jssendgrid の現状 これらは API キーを使用するため、SMTP パスワードよりはマシですが、やはりクライアント側に置くべきではありません。さらに重要なのは、これらのパッケージ名自体が「レガシー(旧世代)」であるという点です。

  • mailgun-js は保守がほぼ停止しており、公式は mailgun.js への移行を案内しています。
  • sendgrid パッケージは非推奨であり、公式は @sendgrid/mail への移行を強く推奨しています。

新しいプロジェクトで mailgun-jssendgrid を選ぶことは、将来のアップデートやセキュリティ修正を受けられなくなることを意味します — これは技術的負債になります。

📊 比較サマリー

特徴nodemaileremailjsmailgun-jssendgrid
プロトコルSMTPSMTPHTTP APIHTTP API
主な環境サーバー (Node.js)サーバー / ブラウザサーバー (Node.js)サーバー (Node.js)
認証情報ユーザー/パスワードユーザー/パスワードAPI キーAPI キー
保守状況✅ 活発✅ 活発⚠️ 停滞 (移行推奨)❌ 非推奨 (移行必須)
フロントエンド❌ 非推奨⚠️ リスクあり❌ 非推奨❌ 非推奨

💡 結論:どう選ぶべきか

プロフェッショナルな開発現場では、以下の基準で選定を行います。

  1. サーバー側で SMTP を使いたいnodemailer が唯一の正解です。安定しており、機能も豊富です。
  2. フロントエンドから直接送りたいemailjs パッケージは使わないでください。代わりに、EmailJS 社の @emailjs/browser SDK を使用します。これなら認証情報を隠せます。
  3. 配信サービス(Mailgun/SendGrid)を使いたい → 必ずサーバー側を介して送信します。そして、パッケージは mailgun-js ではなく mailgun.js を、sendgrid ではなく @sendgrid/mail を選んでください。

メール送信はセキュリティと信頼性が最優先される機能です — 古いパッケージや、認証情報が漏れる実装は避け、最新の公式推奨構成を採用することが、結果的にメンテナンスコストを下げることにつながります。

選び方: emailjs vs mailgun-js vs nodemailer vs sendgrid

  • emailjs:

    SMTP プロトコルでメールを送信したい場合に選択しますが、ブラウザで使うと認証情報が漏れるリスクがあるため注意が必要です。信頼できるサーバー環境内での使用に適しています。フロントエンドから直接送る場合は、セキュリティを強化した公式の @emailjs/browser SDK の検討を強く推奨します。

  • mailgun-js:

    Mailgun サービスを利用したい場合ですが、このパッケージは保守が停滞しているため、新しいプロジェクトでは使用しないでください。代わりに、公式が提供する最新の mailgun.js を使用して、セキュリティと機能のサポートを受けるべきです。

  • nodemailer:

    Node.js サーバー内で SMTP を使ってメールを送りたい場合に選択します。独自の SMTP サーバーや、Gmail などの既存プロバイダーと直接接続する際に最適です。サーバー側の実装において、最も信頼性が高く柔軟な選択肢となります。

  • sendgrid:

    SendGrid サービスを利用したい場合ですが、このパッケージは非推奨です。新しいプロジェクトでは、公式の @sendgrid/mail を使用してください。これにより、最新の API 機能とセキュリティアップデートを利用できます。

emailjs のREADME

emailjs 📧✨

Send emails with ease!

This library lets you send rich HTML emails, attachments (from files, streams, or strings), and plain text messages to any SMTP server.

checks

What's to expect from emailjs? 🚀

  • SSL and TLS Support: Secure connections to your SMTP servers.
  • Authentication Galore: Supports popular SMTP authentication methods like PLAIN, LOGIN, CRAM-MD5, and XOAUTH2.
  • Asynchronous Sending: Emails are queued and sent in the background.
  • Rich Content: Send HTML emails and include multiple attachments.
  • Flexible Attachments: Attachments can be files, data streams, or plain strings.
  • UTF-8 Ready: Full support for UTF-8 in headers and body.
  • Built-in Type Declarations: first-class TypeScript support.
  • Greylisting Awareness: Automatically handles greylisting to improve deliverability.

Get Started! 🛠️

Installing

It's super simple!

npm install emailjs

Requirements

  • Access to an SMTP Server.
  • If your email service (like Gmail) uses two-step verification, you'll need an application-specific password.

Quick Examples 🧑‍💻

Here's how easy it is to send emails:

Text-Only Emails

import { SMTPClient } from 'emailjs';

const client = new SMTPClient({
    user: 'your-username',
    password: 'your-password',
    host: 'smtp.your-email.com',
    ssl: true, // Use SSL for secure connection
});

async function sendMyEmail() {
    try {
        const message = await client.sendAsync({
            text: 'Hello from emailjs! This is a test message.',
            from: 'You <your-email@example.com>',
            to: 'Someone <someone@example.com>',
            subject: 'Exciting News from emailjs! 🎉',
        });
        console.log('Email sent successfully:', message);
    } catch (err) {
        console.error('Failed to send email:', err);
    } finally {
        client.smtp.close(); // Don't forget to close the connection!
    }
}

sendMyEmail();

HTML Emails & Attachments

import { SMTPClient, Message } from 'emailjs';

const client = new SMTPClient({
    user: 'your-username',
    password: 'your-password',
    host: 'smtp.your-email.com',
    tls: true,
});

async function sendRichEmail() {
    const htmlContent = `
        <h1>Greetings!</h1>
        <p>This is an <b>HTML email</b> with a lovely picture and an attachment.</p>
        <img src="https://raw.githubusercontent.com/eleith/emailjs/HEAD/cid:my-image" alt="Embedded Image" width="150" height="100">
        <p>Check out the attached file!</p>
    `;

    const message = new Message({
        from: 'You <your-email@example.com>',
        to: 'Someone <someone@example.com>',
        subject: 'Your Awesome HTML Email! 🖼️📄',
        attachment: [
            {
                data: htmlContent,
                alternative: true, // This part is the HTML body
                contentType: 'text/html',
            },
            {
                path: 'path/to/your/document.pdf', // Attach a file from disk
                type: 'application/pdf',
                name: 'document.pdf',
            },
            {
                path: 'path/to/your/image.jpg', // Embed an image for the HTML
                type: 'image/jpeg',
                name: 'cool_image.jpg',
                // Reference in HTML with cid:my-image
                headers: { 'Content-ID': '<my-image>' },
            },
        ],
    });

    try {
        await client.sendAsync(message);
        console.log('Rich email sent successfully!');
    } catch (err) {
        console.error('Failed to send rich email:', err);
    } finally {
        client.smtp.close();
    }
}

sendRichEmail();

API Reference 📖

The emailjs library is fully typed, here is a brief overview of most likely to be used methods

new SMTPClient(options)

Create a new client instance to connect to your SMTP server.

const options = {
    user: 'your-username', // 🔑 Username for logging into SMTP
    password: 'your-password', // 🤫 Password for logging into SMTP
    host: 'smtp.your-email.com', // 🌐 SMTP server host (defaults to 'localhost')
    port: 587, // 🔌 SMTP port (defaults: 25 unencrypted, 465 SSL, 587 TLS)
    ssl: true, // 🔒 Boolean or object for immediate SSL connection
    tls: true, // 🔐 Boolean or object (see typescript types) to initiate STARTTLS
    timeout: 5000, // ⏳ Max milliseconds to wait for SMTP responses
    domain: 'your-domain.com', // 🏠 Domain to greet SMTP with (defaults to os.hostname)
    authentication: ['PLAIN', 'LOGIN'], // 🤝 Preferred authentication methods
    logger: console, // 📝 Override the built-in logger (e.g., custom logging)
};

SMTPClient#send(message, callback)

Sends an email message. You can pass a Message instance or a headers object.

client.send(messageObject, (err, details) => {
    if (err) console.error(err);
    else console.log('Message sent:', details);
});

SMTPClient#sendAsync(message)

a promise-based way to send emails! ✨

try {
    const details = await client.sendAsync(messageObject);
    console.log('Message sent:', details);
} catch (err) {
    console.error('Failed to send:', err);
}

new Message(headers)

Constructs an RFC2822-compliant message object.

const headers = {
    from: 'sender@example.com', // 💌 Sender (required!)
    to: 'recipient@example.com', // 📬 Recipients (at least one of to, cc, or bcc)
    cc: 'carbon-copy@example.com', // 👥 CC recipients
    bcc: 'blind-copy@example.com', // 🕵️‍♀️ BCC recipients
    subject: 'Your Subject Here', // 📝 Email subject
    text: 'Plain text body.', // 🗒️ Plain text content
    attachment: [{ data: 'Hello!' }], // 📎 One or more attachments
};

Message#attach(options)

Adds an attachment to the message. Can be called multiple times.

message.attach({
    path: 'path/to/file.zip', // 📁 Path to a file on disk
    data: 'Binary content as string or buffer', // 📄 Raw data
    stream: fs.createReadStream('file.jpg'), // 🌊 A readable stream
    type: 'application/zip', // MIME type
    name: 'custom-name.zip', // Filename perceived by recipient
    alternative: true, // attach inline as an alternative (e.g., HTML body)
    inline: true, // If true, attached inline (e.g., for <img src="https://raw.githubusercontent.com/eleith/emailjs/HEAD/cid:...">)
    headers: { 'X-Custom-Header': 'value' }, // Custom attachment headers
});

Message#checkValidity()

Synchronously validates that a Message is properly formed before sending.

const { isValid, validationError } = message.checkValidity();
if (!isValid) {
    console.error('Message is invalid:', validationError);
}

Authors ✍️

  • eleith
  • zackschuster

Testing 🧪

# Run all tests
npm test

# Run tests with code coverage report
npm run test:coverage

Development 🧑‍💻🌱

for a local smtp testing experience, use our Mailpit compose service

1. Start Mailpit with Docker Compose

Ensure you have Docker and Docker Compose installed.

# From the project root, start Mailpit
docker compose up

Mailpit will be accessible via:

  • Web UI: http://localhost:8025
  • SMTP Server: localhost:1025

2. Run Example Sending Scripts

You can use the provided scripts to send different types of emails to your local Mailpit instance.

First, make sure the emailjs library is built:

npm run build

Then, run any of the example scripts:

# Send a plain text email
node scripts/send-text.js

# Send an HTML email
node scripts/send-html.js

# Send an email with attachments
node scripts/send-attachment.js

After running a script, open your Mailpit Web UI (http://localhost:8025) to see the emails stream in! 📩