a sveltekit multi-account email client
  • TypeScript 57.3%
  • Svelte 41.1%
  • JavaScript 1.1%
  • HTML 0.5%
Find a file
2025-10-31 21:07:16 +01:00
src feat: persist accounts in sqlite 2025-10-31 21:07:16 +01:00
static feat: persist accounts in sqlite 2025-10-31 21:07:16 +01:00
.gitignore feat: persist accounts in sqlite 2025-10-31 21:07:16 +01:00
.npmrc feat: persist accounts in sqlite 2025-10-31 21:07:16 +01:00
LICENSE Initial commit 2025-10-28 20:49:14 +01:00
package.json feat: persist accounts in sqlite 2025-10-31 21:07:16 +01:00
PLAN.md feat: persist accounts in sqlite 2025-10-31 21:07:16 +01:00
README.md feat: persist accounts in sqlite 2025-10-31 21:07:16 +01:00
svelte.config.js feat: persist accounts in sqlite 2025-10-31 21:07:16 +01:00
tsconfig.json feat: persist accounts in sqlite 2025-10-31 21:07:16 +01:00
vite.config.ts feat: persist accounts in sqlite 2025-10-31 21:07:16 +01:00

unibox

Minimal SvelteKit frontend for a self-hosted IMAP inbox. The app connects to your mail server through a lightweight middleware layer that streams data directly from IMAP—no local database required.

Accounts

Before starting the server, provide Unibox with a persistent store and encryption key for account credentials:

# generate a 32-byte key and keep it safe
export ACCOUNTS_ENCRYPTION_KEY="$(openssl rand -base64 32)"

# optional: choose where the SQLite database lives (defaults to ./data/accounts.sqlite)
export ACCOUNTS_DB_PATH="/path/to/accounts.sqlite"

Launch the dev server and visit /app/accounts to add IMAP connections. Credentials are encrypted at rest inside the SQLite database and decrypted only when establishing an IMAP session.

⚠️ Keep the encryption key secure—anyone with the key and database can recover stored passwords. Rotate the key by re-encrypting the database contents when needed.

Scripts

npm install      # install dependencies
npm run dev      # start the SvelteKit dev server
npm run build    # create a production build
npm run preview  # preview the production build locally

Current limitations

  • Each thread maps to a single IMAP message; conversation grouping requires provider-specific extensions (e.g., X-GM-THRID) and isnt implemented yet.
  • Message bodies are fetched on demand and streamed without additional sanitisation beyond what mailparser provides.
  • Sending and archiving actions are stubs—bridging to SMTP or custom folders is a future enhancement.