TSKit sends transactional emails using React Email for templates and Resend as the default delivery provider. The email driver is swappable - SendGrid is also supported.
Setting up Resend
Section titled “Setting up Resend”Resend is the default provider.
- Create a Resend account.
- Go to API Keys and create a new key.
- Add it to your
.env:
EMAIL_PROVIDER=resendEMAIL_FROM=onboarding@resend.devRESEND_API_KEY=re_...For development, you can use the default onboarding@resend.dev sender address. For production, you need to verify your own domain under Domains in the Resend dashboard and update EMAIL_FROM to an address on that domain.
Setting up SendGrid
Section titled “Setting up SendGrid”To use SendGrid instead of Resend:
- Create a SendGrid account.
- Go to Settings > API Keys and create a key with “Mail Send” permissions.
- Verify a sender identity under Settings > Sender Authentication. SendGrid requires either a verified single sender or domain authentication before it will deliver emails.
- Add it to your
.env:
EMAIL_PROVIDER=sendgridEMAIL_FROM=you@your-domain.comSENDGRID_API_KEY=SG....How it works
Section titled “How it works”The email system follows the same config-driver-facade pattern as storage and payment:
config/mail.tsdefines email channels with provider and credentials.core/drivers/email/implements theEmailDriverinterface for each provider.lib/facades/mailer.tsprovides themailerfacade that loads templates, renders them, and sends.
Sending an email
Section titled “Sending an email”Use the mailer.send() function. The template name is the file name without the extension:
await mailer.send('verify-email', 'user@example.com', { name: 'Jane', url: 'https://app.example.com/verify?token=abc',})The function is type-safe. TypeScript knows which props each template expects based on the type map in emails/index.ts.
Built-in templates
Section titled “Built-in templates”TSKit ships with six email templates:
| Template | When it’s sent |
|---|---|
verify-email | After signup, to verify the email address |
reset-password | When a user requests a password reset |
password-changed | After a password is changed |
subscription-created | After a new subscription is created |
payment-failed | When a payment fails |
team-invitation | When a user is invited to a team |
Each template file in src/emails/ exports two things: a subject function that returns the email subject line, and a default React component for the email body.
Previewing templates
Section titled “Previewing templates”Run the React Email dev server to preview templates in your browser:
bun run email:devThis starts a preview server on port 3001 where you can see each template rendered with sample data.
Adding a new template
Section titled “Adding a new template”See the Adding an Email Template reference for step-by-step instructions.
Adding a new provider
Section titled “Adding a new provider”To add a provider beyond Resend and SendGrid, implement the EmailDriver interface in core/drivers/email/ and register it in the driver factory. See the Adding a Driver reference for the general pattern.
Key files
Section titled “Key files”| File | Purpose |
|---|---|
lib/facades/mailer.ts | Mailer facade (template loading, rendering, sending) |
config/mail.ts | Email channel config (provider, credentials) |
core/drivers/email/resend.ts | Resend driver |
core/drivers/email/sendgrid.ts | SendGrid driver |
core/drivers/email/types.ts | EmailDriver interface |
emails/index.ts | Template registry and type map |
emails/*.tsx | Individual email templates |