npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kardoe/better-auth-aws-ses

v1.0.0

Published

AWS SES email plugin for Better Auth - zero external dependencies, uses native Web Crypto API

Readme

@kardoe/better-auth-aws-ses

AWS SES email plugin for Better Auth - zero external dependencies, uses native Web Crypto API.

Features

  • Zero Dependencies: Uses native Web Crypto API for AWS SigV4 signing - works in Node.js, Cloudflare Workers, Deno, and Bun
  • Beautiful Email Templates: Pre-built responsive HTML templates with dark mode support
  • Multiple Email Types: Magic links, OTP codes, password reset, email verification, welcome emails, organization invitations, and account deletion
  • Combo Auth: Combined magic link + OTP emails for better UX
  • Rate Limiting: Built-in rate limiting support
  • Fully Typed: Complete TypeScript support

Installation

npm install @kardoe/better-auth-aws-ses
# or
pnpm add @kardoe/better-auth-aws-ses
# or
yarn add @kardoe/better-auth-aws-ses

Quick Start

Server Setup

import { betterAuth } from "better-auth";
import { awsSESPlugin } from "@kardoe/better-auth-aws-ses";

export const auth = betterAuth({
  // ... your config
  plugins: [
    awsSESPlugin({
      // AWS SES Configuration
      region: process.env.AWS_REGION!,
      accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,

      // Email Settings
      fromEmail: "[email protected]",
      fromName: "My App",
      replyTo: "[email protected]",

      // App Settings
      appName: "My App",
      appUrl: "https://example.com",
      supportEmail: "[email protected]",

      // Optional: Company info for email footer
      companyName: "My Company",
      companyAddress: "123 Main St, City, Country",

      // Optional: Enable combo auth (magic link + OTP in same email)
      useComboAuthEmail: true,

      // Optional: Rate limiting
      rateLimit: {
        maxEmailsPerHour: 10,
        maxEmailsPerDay: 50,
      },
    }),
  ],
});

Client Setup

import { createAuthClient } from "better-auth/client";
import { awsSESClientPlugin } from "@kardoe/better-auth-aws-ses/client";

export const authClient = createAuthClient({
  plugins: [awsSESClientPlugin()],
});

API Endpoints

The plugin adds the following API endpoints:

| Endpoint | Method | Description | |----------|--------|-------------| | /api/auth/ses/send-verification | POST | Send email verification | | /api/auth/ses/send-password-reset | POST | Send password reset email | | /api/auth/ses/send-magic-link | POST | Send magic link email | | /api/auth/ses/send-otp | POST | Send OTP code email | | /api/auth/ses/send-welcome | POST | Send welcome email | | /api/auth/ses/send-organization-invitation | POST | Send org invitation | | /api/auth/ses/send-email | POST | Send custom email | | /api/auth/ses/status | GET | Check email configuration status |

Email Templates

All templates are responsive, support dark mode, and include plain text fallbacks.

Available Templates

  • Email Verification - For verifying new user email addresses
  • Password Reset - For password reset requests with security warnings
  • Magic Link - Passwordless sign-in links
  • Email OTP - One-time password codes
  • Combo Auth - Magic link + OTP in the same email
  • Welcome - Welcome email for new users
  • Organization Invitation - Inviting users to organizations
  • Delete Account - Account deletion confirmation

Customizing Templates

You can import and customize the templates:

import { emailTemplates, baseEmailWrapper } from "@kardoe/better-auth-aws-ses/templates";

// Use a built-in template
const html = emailTemplates.magicLink.htmlTemplate({
  email: "[email protected]",
  url: "https://example.com/auth/verify?token=...",
  token: "abc123",
  appName: "My App",
  appUrl: "https://example.com",
});

// Or create a custom email with the base wrapper
const customHtml = baseEmailWrapper({
  appName: "My App",
  appUrl: "https://example.com",
  previewText: "Your custom email",
  content: `
    <h1>Custom Content</h1>
    <p>Your custom email content here...</p>
  `,
});

AWS IAM Policy

Your IAM user/role needs the following permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ses:SendEmail",
        "ses:SendRawEmail"
      ],
      "Resource": "*"
    }
  ]
}

For production, restrict the resource to your verified identities:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ses:SendEmail",
        "ses:SendRawEmail"
      ],
      "Resource": [
        "arn:aws:ses:us-east-1:123456789012:identity/example.com",
        "arn:aws:ses:us-east-1:123456789012:identity/[email protected]"
      ]
    }
  ]
}

AWS SES Setup

  1. Verify your domain or email in AWS SES Console
  2. Request production access if you're in sandbox mode (sandbox only allows sending to verified emails)
  3. Create IAM credentials with SES permissions
  4. Set environment variables:
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key

Configuration Options

| Option | Type | Required | Description | |--------|------|----------|-------------| | region | string | Yes | AWS region (e.g., "us-east-1") | | accessKeyId | string | Yes | AWS access key ID | | secretAccessKey | string | Yes | AWS secret access key | | fromEmail | string | Yes | Sender email address | | fromName | string | Yes | Sender display name | | appName | string | Yes | Application name | | appUrl | string | Yes | Application URL | | replyTo | string | No | Reply-to email address | | supportEmail | string | No | Support email for templates | | supportUrl | string | No | Support URL for templates | | companyName | string | No | Company name for footer | | companyAddress | string | No | Company address for footer | | appTagline | string | No | App tagline for welcome emails | | useComboAuthEmail | boolean | No | Enable combo auth emails | | internalApiKey | string | No | API key for internal calls | | rateLimit | object | No | Rate limiting configuration |

Utility Functions

The package exports utility functions for security:

import {
  isValidEmail,
  escapeHtml,
  sanitizeUrl,
  sanitizeUserInput,
} from "@kardoe/better-auth-aws-ses";

// Validate email format
if (isValidEmail("[email protected]")) {
  // Valid email
}

// Escape HTML to prevent XSS
const safe = escapeHtml("<script>alert('xss')</script>");

// Sanitize URLs for email templates
const safeUrl = sanitizeUrl("https://example.com/callback");

// Sanitize user input for display
const safeName = sanitizeUserInput(userProvidedName, 100);

TypeScript

Full TypeScript support with exported types:

import type {
  SESConfig,
  AWSCredentials,
  SignatureParams,
} from "@kardoe/better-auth-aws-ses";

import type {
  EmailTemplateData,
  MagicLinkData,
  PasswordResetData,
  EmailVerificationData,
  EmailOTPData,
  ComboAuthData,
  WelcomeData,
  OrganizationInvitationData,
  DeleteAccountData,
} from "@kardoe/better-auth-aws-ses/templates";

Runtime Support

This plugin works in:

  • Node.js 18+
  • Cloudflare Workers
  • Deno
  • Bun
  • Any runtime with Web Crypto API support

License

MIT