Loading components
Add persistent, retried email delivery to Convex apps with Plunk or Resend adapters, scheduling, deduplication, and webhook-based delivery tracking.
npm install @clipin/convex-emailsConvex 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.
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.
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.
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.
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.
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.
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.
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.
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.