
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
@vibemailai/sdk
Advanced tools
Official SDK for the VibeMail transactional email API. Works in Node 18+, Bun and Deno. No runtime dependencies.
npm install @vibemailai/sdk
import { VibeMail } from "@vibemailai/sdk";
const vibemail = new VibeMail({ apiKey: process.env.VIBEMAIL_API_KEY! });
const { id } = await vibemail.send({
from: "hello@yourdomain.com",
to: "ada@example.com",
subject: "Welcome",
html: "<p>Glad you're here.</p>",
text: "Glad you're here.",
});
The call returns once the API has accepted the message, not once it has been delivered. Use emails.get(id) to follow it.
Always send a text alternative alongside html. Mail with no plain-text part is measurably more likely to be spam-foldered.
One message goes to one recipient. To reach several people, use batch() — it sends a separate message to each, which is also what stops your recipients from seeing one another's addresses:
await vibemail.emails.batch([
{ to: "ada@example.com", subject: "Welcome", text: "Hi Ada" },
{ to: "alan@example.com", subject: "Welcome", text: "Hi Alan" },
]);
Each entry succeeds or fails on its own; one bad address does not sink the rest.
const { data } = await vibemail.emails.batch(messages);
for (const result of data) {
if ("error" in result) console.warn("rejected:", result.error);
}
Pass an idempotencyKey on anything you might retry. A repeat carrying the same key returns the original result instead of sending a second copy — which matters because a client that times out has no way of knowing whether the message went out.
await vibemail.send({
to: "ada@example.com",
subject: "Receipt",
text: "Thanks!",
idempotencyKey: `receipt-${orderId}`,
});
The SDK retries 429 and 5xx responses on its own (twice by default, honouring Retry-After) and never retries a request the server rejected on its merits. Set maxRetries: 0 to handle that yourself.
const { id } = await vibemail.send({
to: "ada@example.com",
subject: "Reminder",
text: "Standup in 15 minutes.",
scheduledAt: "in 2 hours", // or a Date, or an ISO 8601 string
});
await vibemail.emails.cancel(id); // while it is still scheduled
Up to 30 days ahead. Once the dispatcher has claimed a message it is on its way out and can no longer be withdrawn.
const templates = await vibemail.templates.list();
await vibemail.send({
to: "ada@example.com",
template: "welcome",
variables: { name: "Ada" },
});
Anything you pass explicitly — subject, html, text — overrides the stored template, so you can vary one part without redefining the rest.
import { WelcomeEmail } from "./emails/welcome";
await vibemail.send({
to: "ada@example.com",
subject: "Welcome",
react: <WelcomeEmail name="Ada" />,
});
Requires @react-email/render as an optional peer dependency:
npm install @react-email/render react
Your component is rendered in your process, not on our servers. It may close over anything in your application, and shipping it elsewhere to execute would mean handing us your code and your data; what leaves is plain HTML you can inspect. A plain-text alternative is generated automatically unless you pass text.
import { VibeMailError, VibeMailTimeoutError } from "@vibemailai/sdk";
try {
await vibemail.send({ to: "ada@example.com", subject: "Hi", text: "..." });
} catch (err) {
if (err instanceof VibeMailError) {
console.error(err.status, err.detail); // 422, "'to' and 'subject' are required"
if (err.isRetryable) { /* 429 or 5xx */ }
} else if (err instanceof VibeMailTimeoutError) {
// exceeded `timeout`, default 30s
}
}
| Option | Default | |
|---|---|---|
apiKey | — | Required. |
baseUrl | https://vibemail.ai | Point at a self-hosted deployment. |
timeout | 30000 | Per-request, in milliseconds. |
maxRetries | 2 | Applies to 429 and 5xx only. |
fetch | global fetch | Supply your own for tests or proxying. |
send(input) | Shorthand for emails.send. |
emails.send(input) | Send one message. |
emails.batch(inputs, opts?) | Send many, one recipient each. |
emails.get(id) | Status of a send. |
emails.cancel(id) | Withdraw a scheduled send. |
templates.list() | Stored templates. |
MIT
FAQs
Official VibeMail SDK for TypeScript, Node and Bun
The npm package @vibemailai/sdk receives a total of 9 weekly downloads. As such, @vibemailai/sdk popularity was classified as not popular.
We found that @vibemailai/sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.