A modern CLI for sending emails with TypeScript template support, built with Bun. Supports multiple email providers including Nodemailer (SMTP) and Resend. Optimized for Bun users.
bun add -D @reliverse/relsend
# or globally: bun add -g @reliverse/relsend
bun relsend <command> [options]
# or globally: relsend <command> [options]
# 1. Setup configuration
cp .env.example .env
# Edit .env with your email settings
# 2. Send your first email
# Using Nodemailer (default)
bun relsend send --to "[email protected]" --subject "Hello" --text "This is a test email" --from 1
# Using Resend
bun relsend send --provider resend --apiKey re_123456789 --to "[email protected]" --subject "Hello" --text "This is a test email"
Relsend supports two email providers:
- Nodemailer (default) - For SMTP servers like Gmail, Outlook, etc.
- Resend - Modern email API with excellent deliverability
First, set up your Gmail App Password at https://myaccount.google.com/apppasswords, then configure Relsend:
# Relsend Configuration
# Copy the .env.example file to .env and fill in your values
# SMTP Server Configuration
RELSEND_HOST=smtp.gmail.com
# RELSEND_PROVIDER=nodemailer
# (465 & secure=true; 587 & secure=false)
RELSEND_PORT=587
RELSEND_SECURE=false
RELSEND_AUTH_TYPE=password
# [Auth Type]: Authentication
[email protected]
RELSEND_USER_PASS_1=your-16-char-app-password
# [email protected]
# RELSEND_USER_PASS_2=app-password-2
# [Auth Type]: OAuth2 Configuration
# RELSEND_AUTH_TYPE=oauth2
# RELSEND_CLIENT_ID=your-oauth-client-id
# RELSEND_CLIENT_SECRET=your-oauth-client-secret
# RELSEND_REFRESH_TOKEN=your-oauth-refresh-token
Alternative: Use the config command to set values programmatically (host/port/secure/auth only — accounts are set via env):
bun relsend config set host=smtp.gmail.com port=587 secure=false
bun relsend config get # Verify configuration
Get your API key from https://resend.com/api-keys, then configure:
# Edit .env with your Resend settings
# RELSEND_PROVIDER=resend
# RELSEND_API_KEY=re_123456789
# (use RELSEND_USER_NAME_<index> and select via --from)
# See all available templates
bun relsend template list
# Get template details and required variables
bun relsend template info welcome
bun relsend template info notification
bun relsend template info newsletter
bun relsend template info my-email
# Using Nodemailer (default)
bun relsend send --template welcome --templateData '{"userName":"John","companyName":"Acme Corp","userEmail":"[email protected]","userRole":"Developer","startDate":"2025-01-15","supportEmail":"[email protected]"}' --to "[email protected]" --from random
# Using Resend
bun relsend send --provider resend --template welcome --templateData '{"userName":"John","companyName":"Acme Corp","userEmail":"[email protected]","userRole":"Developer","startDate":"2025-01-15","supportEmail":"[email protected]"}' --to "[email protected]" --from 1
# Using Nodemailer
bun relsend send --template notification --templateData '{"notificationType":"Alert","title":"System Maintenance","recipientName":"John","message":"Scheduled maintenance tonight at 2 AM","actionRequired":true,"actionText":"Please save your work","deadline":"Tonight at 11 PM","link":"https://status.acme.com","senderName":"IT Team","senderTitle":"System Administrator","companyName":"Acme Corp","priorityColor":"#dc3545"}' --to "[email protected]" --from 2
# Using Resend
bun relsend send --provider resend --template notification --templateData '{"notificationType":"Alert","title":"System Maintenance","recipientName":"John","message":"Scheduled maintenance tonight at 2 AM","actionRequired":true,"actionText":"Please save your work","deadline":"Tonight at 11 PM","link":"https://status.acme.com","senderName":"IT Team","senderTitle":"System Administrator","companyName":"Acme Corp","priorityColor":"#dc3545"}' --to "[email protected]" --from 2
# Use react-email Tailwind (default - v3 mode) with Nodemailer
bun relsend send --template my-email --tailwind v3 --templateData '{"userName":"John","companyName":"Acme Corp","ctaUrl":"https://acme.com","ctaText":"Get Started"}' --to "[email protected]"
# Use react-email Tailwind with Resend
bun relsend send --provider resend --template my-email --tailwind v3 --templateData '{"userName":"John","companyName":"Acme Corp","ctaUrl":"https://acme.com","ctaText":"Get Started"}' --to "[email protected]"
# Use manual CSS compilation (v4 mode)
bun relsend send --template my-email --tailwind v4 --templateData '{"userName":"John","companyName":"Acme Corp"}' --to "[email protected]"
# Use no CSS (off mode - for custom CSS files)
bun relsend send --template my-email --tailwind off --templateData '{"userName":"John","companyName":"Acme Corp"}' --to "[email protected]"
Relsend includes built-in newsletter templates for onboarding and advanced features:
# Send onboarding email (randomly selects between onboard and advanced-details)
bun relsend send --template newsletter --to "[email protected]" --from 1
# Using Resend
bun relsend send --provider resend --template newsletter --to "[email protected]" --from 1
The newsletter template includes two variants:
- Onboard Email: Welcome new users with quick start guide, key features, and setup instructions
- Advanced Details Email: Comprehensive technical guide covering architecture, TypeScript templates, providers, and production best practices
Both templates feature modern design with Tailwind CSS, responsive layouts, and comprehensive Relsend documentation.
# Using Nodemailer (default)
bun relsend send --to "[email protected]" --subject "Hello" --text "This is a test email"
# Using Resend
bun relsend send --provider resend --to "[email protected]" --subject "Hello" --text "This is a test email"
You can override any configuration from your .env
file by passing flags:
# Override sender email for this specific email
bun relsend send --to "[email protected]" --from "[email protected]" --subject "Hello"
# Override provider and settings for this specific email
bun relsend send --provider resend --apiKey re_123456789 --to "[email protected]" --subject "Hello"
# Override SMTP settings for this specific email
bun relsend send --to "[email protected]" --host "smtp.outlook.com" --port 587 --user "[email protected]" --pass "outlook-password" --subject "Hello"
Relsend uses the following environment variables for configuration:
Variable | Description | Example |
---|---|---|
RELSEND_PROVIDER |
Email provider | nodemailer or resend |
Variable | Description | Example |
---|---|---|
RELSEND_HOST |
SMTP server hostname | smtp.gmail.com |
RELSEND_PORT |
SMTP server port | 587 |
RELSEND_SECURE |
Use SSL/TLS connection | false |
RELSEND_USER_NAME_<i> |
Account email for index i (1..10) | [email protected] |
RELSEND_USER_PASS_<i> |
Account password/app password | your-app-password |
RELSEND_AUTH_TYPE |
Authentication type | password or oauth2 |
RELSEND_CLIENT_ID |
OAuth2 client ID | your-oauth-client-id |
RELSEND_CLIENT_SECRET |
OAuth2 client secret | your-oauth-client-secret |
RELSEND_REFRESH_TOKEN |
OAuth2 refresh token | your-oauth-refresh-token |
Variable | Description | Example |
---|---|---|
RELSEND_API_KEY |
Resend API key | re_123456789 |
Relsend supports two email providers, each with their own advantages:
- Best for: Traditional SMTP servers (Gmail, Outlook, custom SMTP)
- Authentication: App passwords, OAuth2
- Configuration: SMTP host, port, credentials
- Use case: When you have existing SMTP infrastructure
- Best for: Modern applications requiring high deliverability
- Authentication: API key
- Configuration: Simple API key setup
- Use case: When you want excellent deliverability and simple setup
# Use Nodemailer (default)
bun relsend send --to [email protected] --subject "Hello" --text "Hello World"
# Use Resend explicitly
bun relsend send --provider resend --apiKey re_123456789 --to [email protected] --subject "Hello" --text "Hello World"
# Set default provider in .env
echo "RELSEND_PROVIDER=resend" >> .env
echo "RELSEND_API_KEY=re_123456789" >> .env
send
- Send emails with templates or raw content using Nodemailer or Resendconfig get|set
- Manage email provider configuration (updates .env file)template list|info
- List and inspect email templateshelp
- Show detailed help with provider options
Relsend supports multiple Tailwind CSS modes for flexible email styling:
-
v3
(default) - Uses react-email Tailwind component with inline styles- Best for: Modern email clients with full CSS support
- Features: Automatic inline styles, email client compatibility
- Requires:
@react-email/tailwind
package
-
v4
- Uses manual CSS compilation fromstyles/dist/output.css
- Best for: Custom Tailwind builds and advanced configurations
- Features: Full control over CSS compilation
- Requires: Manual CSS build process
-
off
- No CSS link (for custom CSS files)- Best for: Custom CSS files or external stylesheets
- Features: Complete control over styling
- Requires: Manual CSS file management
# Default mode (react-email Tailwind)
bun relsend send --template my-email --tailwind v3 --to [email protected] --from random
# Manual CSS mode
bun relsend send --template my-email --tailwind v4 --to [email protected] --from random
# No CSS mode
bun relsend send --template my-email --tailwind off --to [email protected] --from random
For templates using react-email Tailwind (v3 mode), use the Tailwind
component:
import { Button, Head, Html, Tailwind, pixelBasedPreset } from "@react-email/components";
function MyEmail() {
return (
<Html>
<Tailwind
config={{
presets: [pixelBasedPreset],
theme: {
extend: {
colors: {
brand: "#007291",
},
},
},
}}
>
<Head />
<div className="bg-gray-50 p-8">
<Button className="bg-brand px-6 py-3 text-white">
Click me
</Button>
</div>
</Tailwind>
</Html>
);
}
Using .env
files provides several advantages:
- ✅ Security - Keep sensitive credentials out of command history
- ✅ Simplicity - No need to pass SMTP flags with every command
- ✅ Flexibility - Override any setting with command-line flags when needed
- ✅ Portability - Share configuration across different environments
- ✅ Bun Native - Automatic loading without additional dependencies
- ✅ Multiple Email Providers - Nodemailer (SMTP) and Resend support
- ✅ Gmail Support - OAuth2 and App Password authentication via Nodemailer
- ✅ Resend Integration - Modern email API with excellent deliverability
- ✅ TypeScript Templates - Component-based email templates
- ✅ React Email Support - Built-in react-email components with Tailwind
- ✅ Tailwind CSS Integration - Multiple Tailwind modes (v3, v4, off)
- ✅ Environment Variables - Simple .env file configuration
- ✅ Template Variables - Dynamic content with
{{variable}}
syntax - ✅ HTML + Text - Both formats supported
- ✅ Modern CLI - Built with Bun for speed
- ✅ Zero Dependencies - Uses Bun's native environment variable support
- ✅ Visual Feedback - Beautiful spinners for all operations
- ✅ Provider Flexibility - Switch between providers with
--provider
flag
{
from: "[email protected]",
to: "[email protected]",
subject: "Test Email",
text: "Plain text version",
html: "<h1>HTML version</h1>"
}
MIME-Version: 1.0
From: [email protected]
To: [email protected]
Subject: Test Email
Date: Sun, 07 Sep 2025 18:59:05 GMT
Message-ID: <unique-id@domain>
Content-Type: multipart/alternative; boundary="----=_NextPart_000_0000_01DA1234567890"
------=_NextPart_000_0000_01DA1234567890
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
Plain text version
------=_NextPart_000_0000_01DA1234567890
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit
<h1>HTML version</h1>
------=_NextPart_000_0000_01DA1234567890--
- MIME Multipart Structure: Nodemailer creates a structured email with multiple parts separated by boundary markers
- Both Text & HTML: When provided both, it includes both versions
- Email Headers: Adds standard email headers (Date, Message-ID, Content-Type, etc.)
- Encoding: Handles character encoding and transfer encoding
- Fallback Support: Email clients can choose which version to display
- The content parts that will be sent (text and HTML separately)
- Not the raw MIME structure (that's nodemailer's job)
- React components rendered to HTML before sending
- Exactly what the recipient will see in their email client
- Modern clients (Gmail, Outlook, Apple Mail): Display the HTML version
- Text-only clients (some mobile apps, accessibility tools): Show the plain text
- "Show Original" in Gmail: Shows the raw MIME structure
- Fallback behavior: If HTML fails to load, falls back to plain text
We welcome contributions! 👋
TODO:
- Add Panda CSS support
This project is licensed under the Apache-2.0 License Copyright (c) 2025 Nazar Kornienko (blefnk), Bleverse, Reliverse See the LICENSE and NOTICE files for more information.