Sign inGet Started

Node.js SDK

Send email with Bun

Use Parcel Wing from Bun HTTP servers, scripts, and background jobs with the same official Node.js SDK.

Install the SDK

Bun can install and run the official @parcelwing/node package directly.

Terminal

bun add @parcelwing/node

HTTP server

Create a small POST endpoint with Bun.serve and keep the API key in Bun.env.

src/server.ts

import { ParcelWing, ParcelWingError } from "@parcelwing/node";
 
const parcelWing = new ParcelWing({
apiKey: Bun.env.PARCEL_WING_API_KEY!,
});
 
Bun.serve({
port: 3000,
async fetch(request) {
const url = new URL(request.url);
 
if (request.method !== "POST" || url.pathname !== "/send") {
return new Response("Not found", { status: 404 });
}
 
const body = await request.json() as { to: string };
 
try {
const [message] = await parcelWing.emails.send({
from: "Acme <[email protected]>",
to: body.to,
subject: "Hello from Bun",
text: "This email was sent from a Bun server.",
});
 
return Response.json({ id: message?.id });
} catch (error) {
if (error instanceof ParcelWingError) {
return Response.json(
{ code: error.code, requestId: error.requestId },
{ status: error.status },
);
}
 
return Response.json({ error: "Unexpected error" }, { status: 500 });
}
},
});

Script

Bun is also a good fit for internal scripts that send operational emails from trusted environments.

scripts/send-test-email.ts

import { ParcelWing } from "@parcelwing/node";
 
const parcelWing = new ParcelWing({
apiKey: Bun.env.PARCEL_WING_API_KEY!,
});
 
const [message] = await parcelWing.emails.send({
from: "Acme <[email protected]>",
subject: "Hello from a Bun script",
text: "This one-off script can run from CI, a cron job, or your terminal.",
});
 
console.log(message?.id);

Production notes

  • Keep PARCEL_WING_API_KEY out of client-side code and public repositories.
  • Validate request bodies before sending mail from public endpoints.
  • Use templates for emails sent from cron jobs, queues, or internal scripts.