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:

  1. Create an API key. Go to API Keys and create a new key.
  2. 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 the from address 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 ResendApiKey
Please note

Locally, secrets are stored on your machine and injected when you run encore run. No .env files needed.

Initialize the client

resend.ts
import { 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.ts
import { 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.ts
import { 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.