TypeScript Cloudflare Email Worker that forwards inbound email for your domain to multiple verified Cloudflare destination addresses.
- Accepts inbound mail routed to a Cloudflare Email Worker.
- Fans the message out to multiple verified destination mailboxes.
- Optionally prefixes the subject with the alias used.
- Adds
X-Original-Rcpt-ToandX-Original-Mail-Fromheaders for downstream filtering. - Supports basic allow/deny recipient and sender-domain controls.
- Rejects suspicious mail loops.
cf-email-fanout-ts/
├─ .github/
│ └─ copilot-instructions.md
├─ src/
│ └─ index.ts
├─ package.json
├─ README.md
├─ tsconfig.json
└─ wrangler.toml
- Cloudflare account with your domain already using Email Routing.
- Three verified Cloudflare destination addresses already configured.
- Node.js 20+ recommended.
- npm.
npm install
npx wrangler login
npx wrangler deployEdit wrangler.toml:
[vars]
FORWARD_TO = "you1@example.com,you2@example.com,you3@example.com"
ADD_SUBJECT_PREFIX = "true"
SUBJECT_PREFIX_MODE = "alias"
ALLOW_RECIPIENTS = ""
DENY_RECIPIENTS = "abuse@yourdomain.com,postmaster@yourdomain.com"
ALLOWED_SENDER_DOMAINS = ""
DENIED_SENDER_DOMAINS = ""
MAX_MESSAGE_SIZE_BYTES = "20971520"FORWARD_TO: comma-separated verified destination inboxes.ADD_SUBJECT_PREFIX:trueorfalse.SUBJECT_PREFIX_MODE:aliasgives[shopping],fullgives[shopping@yourdomain.com].ALLOW_RECIPIENTS: optional comma-separated exact destination aliases to allow.DENY_RECIPIENTS: optional comma-separated exact aliases to reject.ALLOWED_SENDER_DOMAINS: optional sender domain allow-list.DENIED_SENDER_DOMAINS: optional sender domain deny-list.MAX_MESSAGE_SIZE_BYTES: optional size cap.
- Deploy the worker with
npx wrangler deploy. - Open Cloudflare Dashboard.
- Select your domain.
- Go to Email or Email Routing.
- Open Email Workers or the route creation flow.
- Create a route.
- Set the custom address or broader route pattern you want routed into the worker.
- Choose your deployed worker
cf-email-fanout-tsas the destination. - Save the route.
- Send test mail to one or more aliases on your domain.
Send messages to:
shopping@yourdomain.combanking@yourdomain.comrandom-test-123@yourdomain.com
Then verify:
- all three destination inboxes received the message,
- the subject prefix is present if enabled,
X-Original-Rcpt-Tois visible in headers,- loop detection is not firing unexpectedly.
npm run check
npm run deploy
npm run tail- Email Worker behavior is best tested by sending real mail through Cloudflare Email Routing.
- Downstream mail clients vary in how visibly they surface original recipient headers.
- Catch-all style routing is powerful, but also excellent at inviting spam to dinner.