Beignet API reference
    Preparing search index...

    Module @beignet/provider-mail-resend

    @beignet/provider-mail-resend

    Caution

    Beignet is experimental alpha software. The 0.0.x package line is for early evaluation, and APIs may change between releases while the framework settles.

    Resend-backed mail provider for Beignet.

    The provider installs the app-facing ctx.ports.mailer port and exposes ctx.ports.resend.client only as an escape hatch for Resend-specific features.

    createResendMailProvider(...) returns the stable ResendMailProvider type. ResendMailConfig describes its validated config; the Zod schema remains internal.

    bun add @beignet/provider-mail-resend @beignet/core resend
    

    The provider supports resend ^2, ^3, ^4, and ^6. Resend v6 inherits the SDK's Node.js 20+ runtime requirement.

    import { createResendMailProvider } from "@beignet/provider-mail-resend";
    import { createServer } from "@beignet/core/server";

    const server = await createServer({
    ports: basePorts,
    providers: [createResendMailProvider()],
    context: ({ ports }) => ({ ports }),
    routes,
    });

    Required environment variables:

    Variable Description
    RESEND_API_KEY Resend API key
    RESEND_FROM Default sender, e.g. My App <no-reply@example.com>

    beignet doctor --strict checks that installed Resend mail providers are registered in server/providers.ts and that both required env vars are present in app env examples or config.

    Use createResendMailProvider(...) when you want to pass config directly instead of reading RESEND_* env vars. Options override env-derived values:

    import { createResendMailProvider } from "@beignet/provider-mail-resend";

    export const providers = [
    createResendMailProvider({
    apiKey: secrets.resendApiKey,
    from: "My App <no-reply@example.com>",
    }),
    ];

    Calling createResendMailProvider() with no options uses the env-backed configuration.

    await ctx.ports.mailer.send({
    to: "user@example.com",
    subject: "Welcome",
    html: "<h1>Hello</h1>",
    });

    The same MailerPort works with SMTP, memory fakes, and other adapters:

    await ctx.ports.mailer.send({
    from: { email: "support@example.com", name: "Support" },
    to: ["user@example.com", "admin@example.com"],
    replyTo: "support@example.com",
    subject: "Account updated",
    text: "Your account was updated.",
    html: "<p>Your account was updated.</p>",
    });

    Use the Resend client only when you need a Resend-specific feature not covered by MailerPort:

    await ctx.ports.resend.client.emails.send({
    from: "sender@example.com",
    to: "user@example.com",
    subject: "Invoice",
    html: "<p>Attached.</p>",
    attachments: [
    {
    filename: "invoice.pdf",
    content: pdfBuffer,
    },
    ],
    });

    The provider contributes:

    • ctx.ports.mailer, the standard Beignet MailerPort
    • ctx.ports.resend, an escape hatch with the Resend client and default sender

    When ctx.ports.devtools is installed, this provider records mail.send, mail.sent, and mail.failed events under the mail watcher. Completed and failed events include durationMs in their details.

    The provider fails fast and does not retry. Each send(...) call makes one Resend SDK call, even for transient network errors or provider-side failures. Mail delivery is not idempotent: a timed-out send may still have been delivered, so a blind provider retry risks duplicate emails.

    Delivery failures throw MailDeliveryError from @beignet/core/mail with the provider name, the recipient count, and the original Resend error preserved as cause. Message bodies and credentials are never included. Startup configuration problems throw during provider setup.

    When mail needs retries, dispatch it from a job or an outbox-backed listener and own idempotency there. The job or outbox row should choose attempts and delay, and the application should record one delivery per business event before sending.

    Use a memory or fake MailerPort in use-case tests. Keep Resend sandbox or test-mode credentials in environment-specific config and avoid sending real mail from automated tests.

    Set RESEND_FROM to a verified domain sender. Treat mail delivery as an external side effect: trigger important mail from committed workflow state, usually through notifications, jobs, or outbox-backed listeners.

    MIT

    CreateResendMailerOptions
    CreateResendMailProviderOptions
    ResendMailConfig
    ResendMailEscapeHatch
    ResendMailProviderPorts
    ResendMailProvider
    createResendMailer
    createResendMailProvider