Resend
Resend provides transactional email with high deliverability and React Email templates. This guide shows how to use it with Encore's Pub/Sub and secrets management.
To get started quickly, create a new app from the example:
$ encore app create --example=ts/resend
Or follow the steps below to add Resend to an existing Encore app.
Please note
If you haven't installed Encore yet, see the installation guide first.
Install the SDK
$ npm install resend
If you want to use React Email templates:
$ npm install resend @react-email/components
Resend setup
Before writing code, you'll need to configure a few things in the Resend dashboard:
- Create an API key. Go to API Keys and create a new key.
- Verify a domain (optional for testing). Go to Domains and add your sending domain. Until you verify a domain, you can use
[email protected]as thefromaddress for testing.
See the Resend documentation for more details on domain verification and sending limits.
Set your API key
Store your Resend API key as an Encore secret:
$ encore secret set --type dev,local,pr,production ResendApiKeyPlease note
Locally, secrets are stored on your machine and injected when you run encore run. No .env files needed.
Initialize the client
resend.tsimport { Resend } from "resend";
import { secret } from "encore.dev/config";
const resendApiKey = secret("ResendApiKey");
export const resend = new Resend(resendApiKey());
Send an email
Use the Resend SDK in an Encore API endpoint:
send.tsimport { api } from "encore.dev/api";
import { resend } from "./resend";
interface SendEmailRequest {
to: string;
subject: string;
html: string;
}
interface SendEmailResponse {
id: string;
}
export const sendEmail = api(
{ expose: true, method: "POST", path: "/email/send" },
async (req: SendEmailRequest): Promise<SendEmailResponse> => {
const { data, error } = await resend.emails.send({
from: "Your App <[email protected]>",
to: req.to,
subject: req.subject,
html: req.html,
});
if (error) {
throw new Error(`Failed to send email: ${error.message}`);
}
return { id: data!.id };
}
);
Please note
The from address must use a domain you've verified in Resend. For testing, you can use [email protected] which works with any API key.
Async delivery with Pub/Sub
For better performance, send emails asynchronously using Encore's Pub/Sub. This keeps your API endpoints fast and handles retries automatically:
topic.tsimport { Topic, Subscription } from "encore.dev/pubsub";
import { resend } from "./resend";
interface EmailEvent {
to: string;
subject: string;
html: string;
}
export const emailTopic = new Topic<EmailEvent>("email-send", {
deliveryGuarantee: "at-least-once",
});
const _ = new Subscription(emailTopic, "send-via-resend", {
handler: async (event) => {
const { error } = await resend.emails.send({
from: "Your App <[email protected]>",
to: event.to,
subject: event.subject,
html: event.html,
});
if (error) {
throw new Error(error.message);
}
},
});
Then publish from any endpoint:
import { emailTopic } from "./topic";
// Inside any API endpoint
await emailTopic.publish({
to: "[email protected]",
subject: "Welcome!",
html: "<p>Thanks for signing up.</p>",
});
Please note
Locally, Pub/Sub runs in-process so messages are delivered immediately, making it easy to test and debug.
Deploy
When you deploy, Encore automatically provisions and manages the infrastructure your app needs:
- Secrets encrypted per environment (preview, staging, production), never shared between them.
- Pub/Sub provisioned as GCP Pub/Sub or SQS/SNS on AWS, with automatic retries and dead-letter queues.
- Networking including TLS, load balancing, and DNS.
Self-hosting
Build a Docker image and deploy anywhere:
$ encore build docker my-app:latest
See the self-hosting docs for more details.
Encore Cloud
Deploy your application to a free staging environment in Encore's development cloud:
$ git push encore main
You can also connect your own AWS or GCP account and Encore will automatically provision Pub/Sub topics, manage secrets, and handle networking in your cloud. See Connect your cloud account for details.