Self-hosted email backup and search. Connect any IMAP account, sync your entire history, and search years of mail with Meilisearch-powered full-text search. Keep your archive under your control.
Stack
- SvelteKit — Frontend UI, server-rendered and served on its own dev port.
- Node.js API + Workers — Separate backend service plus background workers for IMAP sync — both run alongside the frontend via npm workspaces.
- PostgreSQL + Drizzle ORM — Type-safe schema and migrations for accounts, messages, and folders.
- Meilisearch — Full-text search across subjects, bodies, and attachments.
- Valkey/Redis — Backs the background job queue that drives IMAP sync.
Features
- IMAP sync — Connect Gmail, Outlook, or any IMAP provider. Sync your entire mailbox history in the background.
- Full-text search — Meilisearch indexes subjects, bodies, and attachment names. Find any email in milliseconds.
- Clean web interface — Browse folders, read threads, and search your archive from a fast, responsive SvelteKit UI.
- Self-hosted — Frontend, backend API, and workers all run on your own infrastructure. No third-party access to your mail.
Install
git clone https://github.com/yashthakur1/MailVault.git
cd MailVault
npm install
cp .env.example .envEnvironment
DATABASE_URL=postgresql://user:pass@localhost:5432/mailvault
MEILI_HOST=http://localhost:7700
MEILI_MASTER_KEY=your-master-key-here
REDIS_HOST=localhost
REDIS_PORT=6379
JWT_SECRET=your-secure-random-stringWalkthrough
1. Clone the repository
Clone the monorepo and move into the project directory.
git clone https://github.com/yashthakur1/MailVault.git
cd MailVault2. Install dependencies
Install all monorepo dependencies using npm workspaces — this covers the frontend, backend API, and workers in one pass.
npm install3. Configure environment variables
Copy .env.example to .env and fill in your database, search, and queue credentials — DATABASE_URL, MEILI_HOST/MEILI_MASTER_KEY, REDIS_HOST/REDIS_PORT, and a JWT_SECRET for auth.
cp .env.example .env4. Run database migrations
Generate and apply Drizzle migrations against your PostgreSQL database.
npm run db:generate
npm run db:migrate5. Start the development environment
One command concurrently runs the SvelteKit frontend (http://localhost:3000), the backend API (http://localhost:4000), and the background workers that handle email ingestion and indexing.
npm run dev:oss6. Build and deploy
Build the production bundles, then start the app server and the background workers as separate long-running processes (e.g. under pm2 or systemd).
npm run build:oss
npm run start:oss
# in a separate terminal or service
npm run start:workersGotchas
- The dev/build/start scripts are the
:ossvariants (dev:oss, build:oss, start:oss) — the plain npm run dev/build won't start the full stack in this monorepo. - Workers run as a separate process from the app server — forgetting to start npm run start:workers in production means mail stops syncing even though the UI still loads.
- IMAP sync can be slow for large mailboxes (100k+ messages) — the initial sync runs in the background and can take hours.
- Gmail requires an app-specific password if you have 2FA enabled. Regular account passwords won't work.
- Meilisearch needs at least 1GB RAM for indexing large archives.
Why not just build it yourself?
If you need a full email client with sending, calendars, and contacts, this isn't it. InboxVault is read-only archival and search, not a replacement for your mail client.
Links
License: MIT
Got stuck, or want this shipped end-to-end for you? bitroot.club builds custom products for founders. →