A self-hosted email client for managing custom domain email. Built with Next.js, shadcn/ui, Tailwind CSS v4, Supabase, and Resend.
- Inbound email via Resend webhooks
- Outbound email sending via Resend SDK
- Magic link authentication (single-user)
- Draft saving and editing
- Real-time updates via Supabase Realtime
- Reply and forward with quoted text
- Dark / light mode (toggle with
d) - PWA-ready — installable on mobile
- Attachment support
Resend (inbound webhook) → /api/inbound → Supabase (emails table)
Resend (send API) ← /actions/send-email ← Composer UI
Supabase Auth (magic link OTP) → /auth/callback
git clone https://github.com/hashimpk/selfmail.git
cd selfmail
pnpm installcp .env.example .env.localEdit .env.local with your values:
| Variable | Description |
|---|---|
RESEND_API_KEY |
Resend API key |
RESEND_WEBHOOK_SECRET |
Resend inbound webhook signing secret |
NEXT_PUBLIC_SUPABASE_URL |
Supabase project URL (Settings → API Keys → Project URL) |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY |
Supabase publishable key (Settings → API Keys → Publishable key) |
SUPABASE_SERVICE_ROLE_KEY |
Supabase secret key — server-side only, never exposed to the browser (Settings → API Keys → Secret key) |
ALLOWED_EMAIL |
Strongly recommended. Email address that can sign in. If unset, any person who can receive a magic link can access the app. |
FROM_NAME |
Display name for outbound emails |
NEXT_PUBLIC_FROM_ADDRESSES |
Comma-separated from-addresses shown in the composer |
NEXT_PUBLIC_APP_DOMAIN |
Your domain for UI branding |
Run the migrations against your Supabase project:
supabase link --project-ref YOUR_PROJECT_REF
supabase db pushOr paste each file from supabase/migrations/ into the Supabase SQL editor in order.
- Verify your domain in the Resend dashboard
- Set up inbound routing pointing to
https://your-deployment.com/api/inbound - Copy the webhook signing secret into
RESEND_WEBHOOK_SECRET
pnpm devOpen http://localhost:3000 and sign in with your email.
Set all environment variables in your Vercel project settings. The inbound webhook URL will be https://your-app.vercel.app/api/inbound.
After cloning, replace these files with your own:
public/icon-192.png,public/icon-512.png— PWA iconspublic/mail_icon.png— sidebar and splash screen iconpublic/manifest.json— updatenameanddescription