Transactional Email Service
Send beautiful transactional emails via Resend or SendGrid — welcome, password reset, invoice, and notification templates included.
Code is provided "as is". Review and test before production use. Terms
Built by Thomas
@thomas
Transactional email service using Resend with 4 pre-built responsive HTML email templates: welcome, password reset, invoice, and notification. Provides a simple API to send templated or raw custom emails.
- Send welcome emails to new users with responsive HTML templates
- Send password reset emails with expiring reset links
- Send invoice emails with itemized line items and totals
- Send notification emails with optional call-to-action buttons
- Send custom raw HTML emails via sendRaw()
Step 1: Install the resend dependency
npm install resendValidation: resend should appear in package.json dependencies
Step 2: Set the RESEND_API_KEY environment variable
export RESEND_API_KEY=re_your_key_hereValidation: RESEND_API_KEY should be set in your environment
Step 3: Import and use the EmailService
import { EmailService } from "./src";
const email = new EmailService();
await email.send("welcome", { to: "user@example.com", name: "Alice" });Validation: Should send an email successfully and return { id, success: true }
EmailServicenew EmailService(options?: { apiKey?: string; from?: string })Creates a new email service. Reads RESEND_API_KEY from env by default. Optional from address defaults to noreply@example.com or EMAIL_FROM env var.
const email = new EmailService();sendsend(template: EmailTemplate, data: TemplateData): Promise<SendResult>Sends a templated email. Templates: welcome, password-reset, invoice, notification. Each template has required and optional data fields.
await email.send("welcome", { to: "user@example.com", name: "Alice" });sendRawsendRaw(options: RawEmailOptions): Promise<SendResult>Sends a custom email with raw HTML. Options: to, subject, html, text (optional), from (optional), replyTo (optional).
await email.sendRaw({ to: "user@example.com", subject: "Hello", html: "<p>Hi!</p>" });- Do not use without setting RESEND_API_KEY — constructor will succeed but send() will throw
- Do not pass HTML in template data fields — templates handle HTML rendering internally
- Only supports Resend as the email provider — no SendGrid or other providers
- No retry logic — failed sends throw immediately
- No attachment support
- Templates are hardcoded — customization requires modifying the source code
RESEND_API_KEYRequiredSensitiveResend API key for sending emailsEMAIL_FROMDefault sender email address (defaults to noreply@example.com if not set)Findings (4)
- -Missing null check on TEMPLATES[template] lookup could throw if invalid template passed
- -No validation of email addresses in 'to' field before sending to Resend API
- -Missing TypeScript strict mode declaration in tsconfig or explicit return type on TEMPLATES record value
- -Documentation claims 'name' is optional for welcome template but type definition shows it as required
Suggestions (6)
- -Add template validation in send() method to throw immediately if invalid template name passed, rather than relying on undefined behavior
- -Implement HTML escaping utility for user-provided fields (name, title, body) to prevent XSS if data comes from untrusted sources
- -Add basic email validation for 'to' field before API call to catch malformed addresses early
- +3 more suggestions