How to send emails using Bun

Render emails server-side and send them crazy fast using Bun and React.

Vitor CapretzVitor Capretz
How to send emails using Bun

What is Bun again?

Bun is an all-in-one runtime for JavaScript. It comes with a bundler, test runner, and package manager.

The best thing about Bun is its speed. It's way faster than Node.js and Deno, which makes it pretty compelling for edge computing.

Since lots of emails are sent via background jobs running in edge functions, we decided to explore how to send emails using Bun.

Starting the HTTP server

To get started, we will create an index.tsx file and include a simple HTTP server that returns a "Hello World" message.

const server = Bun.serve({
port: 3000,
fetch(request) {
return new Response('Hello World!');
},
});
console.log(`Listening on localhost:${server.port}`);

Run the local server by executing bun index.tsx on the terminal. Once you navigate to http://localhost:3000, you will see the message.

Now that we have this foundation, we can add the actual email functionality.

Adding Resend for email sending

First, we import the resend package and create a new client that will authenticate using an Resend API key.

Then, we call the send method and return the response object. In this example, we're sending an email using the html property.

import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
const server = Bun.serve({
port: 3000,
async fetch() {
const data = await resend.emails.send({
from: 'Acme <onboarding@resend.dev>',
to: ['delivered@resend.dev'],
subject: 'Hello World',
html: '<p>It works!</p>',
});
return new Response(JSON.stringify(data));
},
});
console.log(`Listening on http://localhost:${server.port} ...`);

Integrating React Email templates

Being able to send an email using HTML is nice, but being able to use an engine like React Email is even better.

To make things interesting, let's create a new waitlist-email.tsx file that will render a beautiful waitlist email.

import {
Body,
Container,
Head,
Heading,
Html,
Preview,
Text,
} from '@react-email/components';
import * as React from 'react';
interface WaitlistEmailProps {
name: string;
}
export const WaitlistEmail = ({ name }: WaitlistEmailProps) => (
<Html>
<Head />
<Preview>Thank you for joining our waitlist and for your patience</Preview>
<Body style={main}>
<Container style={container}>
<Heading style={h1}>Coming Soon.</Heading>
<Text style={text}>
Thank you {name} for joining our waitlist and for your patience. We
will send you a note when we have something new to share.
</Text>
</Container>
</Body>
</Html>
);
const main = {
backgroundColor: '#000000',
margin: '0 auto',
};
const container = {
margin: 'auto',
padding: '96px 20px 64px',
};
const h1 = {
color: '#ffffff',
fontSize: '24px',
fontWeight: '600',
lineHeight: '40px',
margin: '0 0 20px',
};
const text = {
color: '#aaaaaa',
fontSize: '14px',
lineHeight: '24px',
margin: '0 0 40px',
};

Now that we have this template, we can import it into our index.tsx file and use it to send an email.

import { Resend } from 'resend';
import { WaitlistEmail } from './waitlist-email';
const resend = new Resend(process.env.RESEND_API_KEY);
const server = Bun.serve({
port: 3000,
async fetch() {
const data = await resend.emails.send({
from: 'Acme <onboarding@resend.dev>',
to: ['delivered@resend.dev'],
subject: 'Hello from Bun + Resend + React Email 馃珦馃拰',
react: WaitlistEmail({ name: 'Vitor' }),
});
return new Response(JSON.stringify(data));
},
});
console.log(`Listening on http://localhost:${server.port} ...`);

By running bun index.tsx, you should see the email being sent using React.

Learn more

We're excited to see what you build with Bun and Resend.

If you want to see the full code, you can check out the GitHub repository.