Skip to content
Writing
BunTypeScriptTutorialDevTools

How to Send Transactional Email with Bun and TypeScript (Zero Dependencies)

Stop wrestling with bloated Node.js polyfills. Learn how to send transactional emails in Bun with sub-millisecond cold starts and full TypeScript type safety.

Tayyab MughalFounder & AI Chief7 min read

Why legacy email libraries feel sluggish in Bun

Bun has revolutionized JavaScript backends by delivering sub-millisecond cold starts, native TypeScript execution, and high-performance I/O. Yet most email tutorials still instruct developers to install `nodemailer` alongside dozens of legacy stream polyfills.

In modern cloud environments, transactional email should be dispatched over HTTP/2 with native `fetch` and zero external dependencies.

Method 1: Sending via Bun Native Fetch (Zero Dependencies)

Because Bun has native `fetch` with connection pooling, you can dispatch authenticated emails in four lines of code without installing any packages:

// send.ts — run directly with `bun send.ts`
const response = await fetch('https://api.sadasend.com/v1/emails', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.SADASEND_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    from: 'system@yourdomain.com',
    to: 'user@example.com',
    subject: 'Your authentication code',
    text: 'Your code is: 482-910. Valid for 10 minutes.',
  }),
});

const data = await response.json();
console.log('Dispatched message ID:', data.id);

Method 2: Using the Type-Safe SadaSend SDK

For complex applications, use the lightweight `@sadasend/sdk` package for complete autocomplete, payload validation, and automatic retries:

import { SadaSend } from '@sadasend/sdk';

const sadasend = new SadaSend({ apiKey: process.env.SADASEND_API_KEY });

const result = await sadasend.emails.send({
  from: 'notifications@yourdomain.com',
  to: 'founder@startup.io',
  subject: 'Weekly Infrastructure Report',
  markdown: `
# Weekly Summary
All systems operational.
- **Uptime:** 99.99%
- **Delivery Latency:** 412ms
  `,
});

Microtask Queue Dispatching in Bun

In high-throughput API handlers (such as user signup routes), you never want to block the HTTP response on an external email network request. Use Bun's microtask scheduling:

// In your Bun.serve() route handler:
queueMicrotask(async () => {
  try {
    await sadasend.emails.send({ ...payload });
  } catch (err) {
    console.error('Background send failed:', err);
  }
});

return new Response(JSON.stringify({ status: 'user_created' }), { status: 201 });