Get Started
Self-host your email in ~20 minutes
This guide walks you through cloning Selfmail, wiring up your services, and deploying a fully functional email client for your custom domain.
Clone & Install
Clone the repository and install dependencies.
git clone https://github.com/hasimpk/selfmail.git
cd selfmail
pnpm installConfigure Environment Variables
Copy the example environment file and fill in your credentials.
cp .env.example .env.localOpen .env.local and set the following variables:
| Variable | Where to find it | Required |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | Supabase → Settings → API Keys → Project URL | Yes |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | Supabase → Settings → API Keys → Publishable key | Yes |
SUPABASE_SERVICE_ROLE_KEY | Supabase → Settings → API Keys → Secret key | Yes |
RESEND_API_KEY | Resend → API Keys → Create API Key | Yes |
RESEND_WEBHOOK_SECRET | Resend → Inbound → your route → Signing Secret | Yes |
FROM_NAME | Your sender display name (e.g. Your Name) | Yes |
NEXT_PUBLIC_FROM_ADDRESSES | Comma-separated sender addresses (e.g. you@yourdomain.com) | Yes |
NEXT_PUBLIC_APP_DOMAIN | Your domain shown in the app header (e.g. yourdomain.com) | Yes |
ALLOWED_EMAIL | Your email address — restricts who can log in | No |
Set Up Supabase
- 1.Go to supabase.com/dashboard and create a new project.
- 2.Once ready, go to Settings → API Keys and copy your Project URL, Publishable key, and Secret key.
- 3.In the SQL Editor, run the migration files found in
supabase/migrations/— run them in order. - 4.Under Authentication → Providers, enable Email and disable email confirmation (magic link only).
- 5.Set your Site URL under Authentication → URL Configuration to your deployed domain (or
http://localhost:3000for local development).
Set Up Resend
- 1.Create a Resend account and verify your custom domain under Domains. Add the DNS records Resend provides.
- 2.Go to API Keys, create a new key, and add it as
RESEND_API_KEY. - 3.Under Inbound, create an inbound route for your domain and set the endpoint to:
https://your-domain.vercel.app/api/inboundCopy the Signing Secret from the inbound route into RESEND_WEBHOOK_SECRET.
Run Locally
Start the development server:
pnpm devOpen localhost:3000 in your browser. Enter your email address to receive a magic link and log in.
Set ALLOWED_EMAIL to your address to restrict access to your account only.
Deploy to Vercel
Deploy using the Vercel CLI:
npx vercel --prodOr import your GitHub repository from the Vercel dashboard. Add all environment variables under Project → Settings → Environment Variables.
Once deployed, update your Resend inbound route URL and Supabase Site URL to your production domain.
Troubleshooting
Common issues
Emails are not appearing in the inbox
Check that your Resend inbound route URL matches your deployed domain exactly (including https://). Verify the webhook is enabled and the signing secret matches RESEND_WEBHOOK_SECRET in your environment.
Magic link login is not working
Ensure Email Auth is enabled in Supabase under Authentication → Providers. Check that your Site URL in Supabase matches your deployed domain. In development, set it to http://localhost:3000.
Database migration errors on first run
Run migration files in order from the supabase/migrations/ folder via the Supabase SQL Editor. If a migration fails, check the error message — it usually points to a missing extension or a table ordering issue.
Inbound emails not routing to the app
Verify your domain's MX records are set to Resend's inbound servers. DNS propagation can take up to 48 hours. Use Resend's domain verification status page to confirm the records are live.
All done
Your inbox is yours now.
Questions or issues? Open an issue on GitHub — contributions are welcome.