Skip to content

About

No description, website, or topics provided.

Resources

Stars

7 stars

Watchers

0 watching

Forks

Repository files navigation

Delivr

Delivr API

A Mail Client that actually Delivers

The backend that powers Delivr — a fast, self-hostable mail service built on Bun & Hono, speaking IMAP and SMTP so your inbox stays yours.


Bun Hono TypeScript Drizzle License

Web Client →  •  Features  •  Quick Start  •  Configuration


✨ Features

  • 📬 Real mail, real protocols — connects to any IMAP/SMTP provider via imapflow and nodemailer; nothing proprietary in the way.
  • 🗂️ Nested mail resources — mail accounts → mailboxes → mails → attachments, modelled cleanly all the way down.
  • 📎 Privacy-first attachments — content is never stored or cached server-side. Attachments are re-fetched from IMAP, parsed in-memory, and streamed out with Cache-Control: no-store.
  • ⚡ Bulk mail actions — move, copy, delete, and flag many messages in one request.
  • 🖼️ BIMI brand logos — resolves sender brand logos from DNS for use as profile pictures; only record metadata is read, the logo is never fetched or stored.
  • 🔐 JWT auth + API keys — token-based sessions plus scoped API keys for programmatic access.
  • 🔒 ECC crypto — mail-backend credentials protected with elliptic-curve encryption and signing.
  • 📖 First-class OpenAPI — every route is documented via hono-openapi and browsable through an embedded Scalar reference.
  • 🗄️ Zero-setup database — SQLite out of the box, with no separate database server to run. PostgreSQL and MySQL schemas exist and runtime support is planned (#10).
  • ⏰ Scheduled tasks — background jobs via the cron package.
  • ✅ Integration-tested — a mock IMAP/SMTP harness exercises the real request paths.

🧱 Tech Stack

Layer Choice
Runtime Bun 1.x
Framework Hono 4.x
Language TypeScript 6.x
ORM Drizzle ORM + Drizzle Kit
Validation Zod 4.x + @hono/standard-validator
API Docs hono-openapi + @scalar/hono-api-reference
Database SQLite (PostgreSQL · MySQL planned)
Mail imapflow (IMAP) · nodemailer (SMTP) · postal-mime
Crypto elliptic (ECC)

🚀 Quick Start

Prerequisites: Bun 1.x

# 1. Install dependencies
bun install

# 2. Configure your environment
cp example.env .env
#    → set DLA_ENCRYPTION_KEY (32 characters) and review the rest

# 3. Run database migrations (SQLite by default)
bun run db:sqlite:migrate

# 4. Start the dev server
bun run dev

The API is now live at http://localhost:14123, with the interactive Scalar reference at /docs/v1 and the raw OpenAPI spec at /docs/v1/openapi (unless DLA_DISABLE_DOCS=true). The root path / redirects to the latest version's docs.

⚙️ Configuration

All configuration is environment-based (see example.env):

Variable Description Default
DLA_LOG_LEVEL Log verbosity info
DLA_APP_URL Required. URL of the Delivr web client —
DLA_API_HOST Bind address ::
DLA_API_PORT Listen port 14123
DLA_DISABLE_DOCS Disable the Scalar API reference false
DLA_MAX_ATTACHMENT_SIZE_MB Maximum combined attachment size per composed mail, in MB, measured before encoding 25
DLA_ENCRYPTION_KEY Required. 32-character key for credential encryption —
DLA_DB_CONNECTION_URL Database connection string / path ./data/db.sqlite
DLA_DB_AUTO_MIGRATE Run migrations on startup true
DLA_DB_MIGRATION_DIR Dir with the migrations files. The compiled binary resolves a relative path next to the executable, not the working directory has to be set manually
DLA_LOG_DIR Log output directory ./data/logs
DLA_CONFIG_BASE_DIR Config base directory ./config
DLA_SMTP_HOST Outbound SMTP host for system mail (e.g. password-reset emails) —
DLA_SMTP_PORT Outbound SMTP port —
DLA_SMTP_USERNAME Outbound SMTP username —
DLA_SMTP_PASSWORD Outbound SMTP password —
DLA_SMTP_FROM From address for system mail —
DLA_SMTP_SECURE Use TLS for the SMTP connection false

Create-mail requests have a total request limit of DLA_MAX_ATTACHMENT_SIZE_MB + 16 MB (41 MB by default), covering both JSON and multipart bodies (mail JSON, attachments and multipart framing). Exceeding this total returns a request-size error; exceeding the separate combined attachment limit returns an attachment-size error. Large text/HTML bodies count toward the total request limit.

The attachment limit counts the files' raw size. Base64 encoding makes the sent message about 37% larger, so 25 MB of attachments become roughly 34 MB on the wire: keep the limit below your mail provider's message size limit divided by 1.37. If the provider still rejects a message as too large, the send request returns a 400 error. Bun itself rejects request bodies over 128 MB, which caps the attachment limit at 112 MB.

🛠️ Commands

Command Description
bun run dev Start dev server with watch mode
bun run typecheck Run TypeScript type checking
bun test Run the test suite
bun run compile Compile the project
bun run start Production entry point
bun run db:sqlite:generate Generate SQLite migrations
bun run db:sqlite:migrate Run SQLite migrations
bun run db:postgresql:generate · :migrate PostgreSQL migrations (schema only, runtime support planned)
bun run db:mysql:generate · :migrate MySQL migrations (schema only, runtime support planned)

🗺️ Project Structure

src/
├── index.ts                # Entry point
├── api/
│   ├── index.ts            # API router setup
│   ├── utils/              # Response helpers, auth, OpenAPI, services
│   └── versions/v1/
│       ├── middleware/     # Auth middleware
│       ├── docs/           # OpenAPI tag definitions (Scalar UI mounted in api/index.ts)
│       └── routes/         # auth · account · mail-accounts · bimi · admin
│                           #   auth → reset-password
│                           #   account → apikeys · preferences
│                           #   mail-accounts → identities · search · mailboxes
│                           #     mailboxes → mail-bulk-actions · mails → attachments
├── db/
│   ├── index.ts            # DB connection
│   └── schema/             # Per-dialect Drizzle schema (sqlite · postgresql · mysql)
└── utils/
    ├── config.ts           # App configuration
    ├── cron.ts             # Scheduled tasks
    ├── crypto/             # ECC encryption & signing
    └── mails/              # Mail backends & parsing

Note: Drizzle schema files are dialect-specific. When adding tables or columns, mirror the change across all three files in src/db/schema/.

📦 The Delivr Project

Repository Description
Delivr API (you are here) The Bun + Hono backend
Delivr Web The Nuxt 4 web client & PWA

📄 License

Licensed under the GNU AGPL-3.0.

Built with 💙 and Bun.

About

No description, website, or topics provided.

Resources

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages