A self-hosted, open-source alternative to Resend for sending transactional emails.
FreeResend allows you to host your own email service using Amazon SES and optionally Digital Ocean for DNS management. It provides a Resend-compatible API so you can use it as a drop-in replacement.
π° Stay updated: Get the latest frontend development insights delivered weekly with Frontend Weekly - curated by the author of FreeResend!
- π 100% Resend-compatible - True drop-in replacement using environment variables
- π Self-hosted - Full control over your email infrastructure
- π§ Amazon SES integration - Reliable email delivery with DKIM support
- π Automatic DNS setup - Integration with Digital Ocean for DNS record creation
- π DKIM authentication - Automatic DKIM key generation and DNS record creation
- π API key management - Generate and manage multiple API keys per domain
- π Email logging - Track all sent emails with delivery status and logs
- π― Domain verification - Automated domain verification with SES
- π Secure - JWT-based authentication and robust API key validation
- π³ Docker ready - Containerized deployment with Docker Compose
- π Comprehensive logging - Detailed email logs with webhook support
- Node.js 18+
- PostgreSQL database (local or hosted)
- Amazon AWS account with SES access
- Digital Ocean account (optional, for automatic DNS management)
- Clone and install dependencies:
git clone <your-repo>
cd freeresend
npm install- Set up environment variables:
cp .env.local.example .env.localEdit .env.local with your configuration:
# Next.js Configuration
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-super-secret-jwt-key-here
# Database Configuration (PostgreSQL)
DATABASE_URL=postgresql://username:password@hostname:port/database
# AWS SES Configuration
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your-aws-access-key
AWS_SECRET_ACCESS_KEY=your-aws-secret-key
# Digital Ocean API Configuration (optional)
DO_API_TOKEN=your-digitalocean-api-token
# Application Configuration
ADMIN_EMAIL=[email protected]
ADMIN_PASSWORD=your-secure-admin-password- Set up the database:
In your Supabase SQL editor, run the contents of database.sql to create all necessary tables.
- Start the development server:
npm run devVisit http://localhost:3000 and log in with your admin credentials.
-
Verify your AWS account for SES:
- Go to AWS SES console
- Move out of sandbox mode if needed
- Configure sending limits
- Create IAM user with SES permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail",
"ses:VerifyDomainIdentity",
"ses:GetIdentityVerificationAttributes",
"ses:DeleteIdentity",
"ses:CreateConfigurationSet",
"ses:VerifyDomainDkim",
"ses:GetIdentityDkimAttributes"
],
"Resource": "*"
}
]
}Note: The DKIM permissions (
ses:VerifyDomainDkim,ses:GetIdentityDkimAttributes) are required for automatic DKIM setup.
If you want automatic DNS record creation:
- Create a Digital Ocean API token with read/write access
- Add your domains to Digital Ocean's DNS management
- Set the
DO_API_TOKENenvironment variable
FreeResend is 100% compatible with the Resend Node.js SDK!
Set the RESEND_BASE_URL environment variable:
export RESEND_BASE_URL="https://your-freeresend-domain.com/api"Then use Resend exactly as before:
import { Resend } from "resend";
// No changes needed - FreeResend API key works with Resend SDK!
const resend = new Resend("your-freeresend-api-key");
const { data, error } = await resend.emails.send({
from: "[email protected]",
to: ["[email protected]"],
subject: "Hello World",
html: "<strong>it works!</strong>",
});const response = await fetch("https://your-freeresend-domain.com/api/emails", {
method: "POST",
headers: {
Authorization: "Bearer your-freeresend-api-key",
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "[email protected]",
to: ["[email protected]"],
subject: "Hello World",
html: "<strong>it works!</strong>",
}),
});POST /api/auth/login- Login with email/passwordGET /api/auth/me- Get current user info
GET /api/domains- List all domainsPOST /api/domains- Add new domainDELETE /api/domains/{id}- Delete domainPOST /api/domains/{id}/verify- Check domain verification
GET /api/api-keys- List API keysPOST /api/api-keys- Create new API keyDELETE /api/api-keys/{id}- Delete API key
POST /api/emails- Send emailGET /api/emails/logs- Get email logsGET /api/emails/{id}- Get specific email
POST /api/webhooks/ses- SES webhook endpoint
-
Add domain in the FreeResend dashboard
-
DNS Records will be automatically created (if Digital Ocean is configured) or displayed for manual setup:
- TXT record -
_amazonses.yourdomain.comfor SES domain verification - MX record -
yourdomain.comfor receiving emails via SES - SPF record -
yourdomain.comfor sender policy framework - DMARC record -
_dmarc.yourdomain.comfor email authentication policy - DKIM records - 3 CNAME records for
*._domainkey.yourdomain.comfor email signing
- TXT record -
-
Verify domain - Click "Check Verification" once DNS records are live
-
Create API key - Generate API keys for your verified domain
-
Start sending - Use the API key with FreeResend or Resend SDK
FreeResend includes test scripts to verify your installation:
# Test with cURL (update variables in script first)
./test-curl.sh# Test direct API + Resend SDK compatibility + Email logs
node test-email.jsBoth scripts will:
- β Send test emails using your API key
- β Verify Resend SDK compatibility
- β Check email logs functionality
- π§ Send actual emails to your inbox for verification
Q: Getting "Invalid API key" errors
- β Make sure you copied the complete API key from the green success message (not the masked version from the table)
- β
API keys have format:
frs_keyId_secretPart(3 parts separated by underscores)
Q: Digital Ocean DNS automation not working
- β Verify your DO API token has Read & Write access to Domains and Domain Records
- β Ensure your domain is added to Digital Ocean's DNS management
- β
Test token:
curl -H "Authorization: Bearer YOUR_TOKEN" https://api.digitalocean.com/v2/domains
Q: Domain verification stuck at "pending"
- β DNS propagation takes 5-30 minutes - be patient!
- β
Check DNS records:
dig TXT _amazonses.yourdomain.com - β Ensure all DNS records are created properly
Q: AWS SES permissions error
- β
Make sure your IAM policy includes DKIM permissions:
ses:VerifyDomainDkimandses:GetIdentityDkimAttributes - β Verify your AWS account is out of SES sandbox mode
Q: Resend SDK not working with FreeResend
- β
Set environment variable:
export RESEND_BASE_URL="https://your-domain.com/api" - β
Use FreeResend API key (starts with
frs_), not Resend API key
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]- Use a production database (Supabase Pro or self-hosted PostgreSQL)
- Set up proper SSL certificates
- Configure firewall rules
- Set up monitoring and logging
- Configure SES with proper sending limits
FreeResend can be deployed on Vercel with some configuration:
- Connect your GitHub repo to Vercel
- Set environment variables in Vercel dashboard
- Deploy
Note: Webhook endpoints might need special configuration for Vercel's serverless environment.
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Start production server
npm start
# Lint code
npm run lintfreeresend/
βββ src/
β βββ app/ # Next.js App Router
β β βββ api/ # API routes
β β β βββ auth/ # Authentication endpoints
β β β βββ domains/ # Domain management
β β β βββ api-keys/ # API key management
β β β βββ emails/ # Email sending & logs
β β β βββ webhooks/ # SES webhook handlers
β β βββ globals.css # Global styles
β β βββ layout.tsx # Root layout
β β βββ page.tsx # Main dashboard page
β βββ components/ # React components
β β βββ Dashboard.tsx # Main dashboard
β β βββ LoginForm.tsx # Authentication
β β βββ *Tab.tsx # Tab components
β βββ contexts/ # React contexts
β βββ lib/ # Core business logic
β βββ supabase.ts # Database client
β βββ auth.ts # Authentication logic
β βββ ses.ts # Amazon SES integration
β βββ digitalocean.ts # DNS automation
β βββ domains.ts # Domain management
β βββ api-keys.ts # API key logic
β βββ middleware.ts # API middleware
βββ database.sql # Database schema
βββ docker-compose.yml # Development setup
βββ test-email.js # Comprehensive test script
βββ test-curl.sh # Quick cURL test
βββ README.md # This file
We welcome contributions! Here's how to get started:
- Fork the repository on GitHub
- Clone your fork:
git clone https://github.com/eibrahim/freeresend.git - Install dependencies:
npm install - Set up environment following the Quick Start guide above
- Run tests:
node test-email.js - Start development:
npm run dev
- π Bug fixes - Always welcome with test cases
- β¨ New features - Open an issue first to discuss
- π Documentation - Improvements always appreciated
- π§ͺ Tests - Required for new features
- π» Code style - Follow existing patterns
- Create a feature branch:
git checkout -b feature/your-feature-name - Make your changes with clear, descriptive commits
- Add tests for new functionality
- Update documentation if needed
- Submit a pull request with a clear description
When reporting bugs, please include:
- Your environment (Node.js version, OS, etc.)
- Steps to reproduce the issue
- Expected vs actual behavior
- Relevant error messages or logs
MIT License - see LICENSE file for details.
- π Documentation: Check SETUP.md for detailed setup instructions
- π Issues: Report bugs via GitHub Issues
- π‘ Feature Requests: Suggest improvements via GitHub Issues
- π Professional Support: Custom development and enterprise support available via EliteCoders
- Email templates support
- Webhook retry mechanism
- Email analytics dashboard
- Multi-user support
- Email scheduling
- SMTP server support
- Email campaign management
FreeResend is built and maintained by Emad Ibrahim - a software engineer and entrepreneur passionate about creating developer tools and open-source solutions.
- π¦ Twitter: @eibrahim - Follow for updates on FreeResend and web development insights
- π§ Email: [email protected]
- π° Newsletter: Frontend Weekly - The best frontend development articles delivered weekly
- πΌ Professional Services: Custom development and enterprise support via EliteCoders
If you need help with:
- ποΈ Custom email infrastructure modifications
- π Enterprise deployments and scaling
- π§ Integration with your existing systems
- π― Feature development beyond the roadmap
Get in touch with EliteCoders β
Building powerful software solutions for businesses worldwide π