Convex Emails

Add persistent, retried email delivery to Convex apps with Plunk or Resend adapters, scheduling, deduplication, and webhook-based delivery tracking.

Installation

npm install @clipin/convex-emails

Benefits

Use cases

how to send transactional emails from Convex with retries

Convex Emails provides a worker function and a sendEmail method that schedule delivery through Convex's built-in scheduler, automatically retrying on transient failures up to a bounded limit. You configure an adapter for Resend or Plunk, call email.sendEmail with an idempotency key and message fields, and the component handles the retry loop and delivery history without additional mutation logic.

how to integrate Resend or Plunk with Convex backend

Convex Emails ships provider adapters imported from @clipin/convex-emails/resend or @clipin/convex-emails/plunk. Each adapter handles HTTP requests, webhook signature verification, and retry classification for its provider. You pass the adapter to the Emails constructor and set RESEND_API_KEY or PLUNK_API_KEY in your deployment environment variables.

deduplicate email sends in Convex mutations

Convex Emails accepts an idempotencyKey string per sendEmail call, which the component uses to prevent duplicate jobs for the same logical send. If the same key is submitted more than once, the component does not create a second delivery job, making it safe to call from retried mutations.

track email delivery status in Convex using webhooks

Convex Emails includes built-in webhook tracking so providers like Resend or Plunk can post delivery events back to your Convex deployment. The component records these events in delivery history, giving application code queryable send status without custom webhook handlers or external state stores.

Frequently asked questions

Does Convex Emails support multiple email providers at the same time?

Convex Emails supports Plunk and Resend as separate adapters. Each route must remain bound to one provider account, and you need a separate worker and webhook route for each account. Switching an existing route to a different adapter does not migrate in-flight jobs.

What happens if an email send fails in Convex Emails?

Convex Emails performs bounded retries managed by the component's scheduler. The retry count is finite, meaning the component will stop attempting delivery after a configured number of failures. The component does not guarantee exactly-once delivery or inbox placement, and an ambiguous result may require manual reconciliation.

Can I use React Email templates with Convex Emails?

Yes. Convex Emails accepts an html string in the sendEmail payload. You can use React Email or any other renderer to produce that string before passing it to sendEmail, keeping template rendering separate from the delivery component.

How do I install and register Convex Emails in my project?

Run npm install @clipin/convex-emails convex, then add app.use(emails) in your convex/convex.config.ts file using the config imported from @clipin/convex-emails/convex.config.js. After registration, create an Emails instance in your functions file with your chosen adapter, export a worker with email.worker(), and call email.sendEmail from your mutations.

Does Convex Emails work without making real HTTP requests during development?

Convex Emails defaults to test mode, which records a test result without sending an actual HTTP request to the provider. You must explicitly disable test mode after verifying your sender and receiver configuration to enable live delivery.

Links

Components

Open-source building blocks for your Convex app

Browse components in this category.

Loading components