Delivr-Project/Delivr-Web

TypeScript

7

255 commits

updated Oct 3, 2026

See the code

See what people are saying

SourceMessageScoreDate

Delivr: A Modern Open Source Mail Client that actually works (r/selfhosted)

Hi everyone, for the past 10 months I've been working on Delivr (with help from a few great contributors), and today I'm releasing version 1.0.0. Why I built it: I wanted a self-hosted mail client that feels as good as Gmail. The open-source webmail clients I tried work, but most of them feel dated…

8

Oct 3, 2026

README

Delivr

Delivr Web

A Mail Client that actually Delivers

A fast, installable webmail client built with Nuxt 4 & Nuxt UI — your inbox, in a clean PWA that stays out of the way.


Nuxt Vue TypeScript Bun PWA License

API Backend →  •  Features  •  Quick Start  •  Configuration


✨ Features

  • 📥 Full mail workflow — browse folders, read threads, compose, and manage flags across multiple mail accounts.
  • 🗂️ Multi-account, multi-folder — switch between mail accounts and drill into any mailbox folder from a single dashboard.
  • 📎 Safe attachments & content — HTML is sanitised with dompurify and a remote-content policy keeps tracking pixels at bay.
  • 🔑 Accounts & API keys — sign in, reset passwords, manage security settings, and issue API keys from the UI.
  • 🛡️ Admin tools — user administration for instance operators.
  • 📱 Installable PWA — @vite-pwa/nuxt with auto-update, offline shell, and a native app-like experience.
  • 🌗 Dark by default — a focused, dark-first interface built on Nuxt UI 4 and Lucide icons.
  • 🔌 Type-safe API client — fully generated from the Delivr API's OpenAPI spec, so the frontend and backend never drift.

🧱 Tech Stack

LayerChoice
RuntimeBun 1.x
FrameworkNuxt 4.x (SSR)
UINuxt UI 4.x (Reka UI) + Lucide icons
LanguageTypeScript 6.x + Vue 3 + Vue Router 5
API Client@hey-api/openapi-ts (generated)
ValidationZod 4.x
PWA@vite-pwa/nuxt
Sanitizationdompurify

🚀 Quick Start

Prerequisites: Bun 1.x, and a running Delivr API instance.

# 1. Install dependencies
bun install

# 2. Configure your environment
cp example.env .env
#    → point DELIVR_API_URL at your running Delivr API

# 3. Start the dev server
bun run dev

Open http://localhost:14128 and sign in.

💡 Regenerating the API client: the frontend talks to the backend through a generated client. Keep the API running and up to date, then run bun run api-client:generate. Never hand-edit the *.gen.ts files.

🐳 Docker

Want to run the whole thing, API included? The Delivr API repository has a docker-compose.yml that starts both with one command. That's usually the easiest way.

If you already have an API running somewhere and just need the web client, grab the ready-made image:

docker run -d -p 14128:14128 \
  -e NUXT_PUBLIC_API_URL=https://api.example.com/v1 \
  -e NUXT_PUBLIC_APP_URL=https://mail.example.com \
  ghcr.io/delivr-project/delivr-web:latest

Or with Compose: DELIVR_API_URL=https://api.example.com/v1 docker compose up -d. To update, run docker compose pull && docker compose up -d.

Want to build it yourself instead? docker build -f docker/Dockerfile -t delivr-web . (or add --build to the Compose command).

You configure the image when you start it, so one build works for any setup:

VariableWhat it doesDefault
NUXT_PUBLIC_API_URLWhere the API lives, including /v1http://localhost:14123/v1
NUXT_PUBLIC_APP_URLThe address of this web clienthttp://localhost:14128
NUXT_PUBLIC_IS_SIGNUP_ENABLEDSet to true to show the sign-up link on the login pagefalse
PORTPort inside the container14128

Keep in mind that the API URL is used by your browser, not by the container, so it has to be an address you can open yourself. On the API side, DLA_APP_URL must point to this web client, or the browser will block the requests (CORS).

⚙️ Configuration

Environment-based configuration (see example.env):

VariableDescriptionDefault
DELIVR_API_URLBase URL of the Delivr API (v1)http://localhost:14123/v1
DELIVR_APP_URLPublic URL of this web apphttp://localhost:14128
DELIVR_ENABLE_SIGNUPAllow self-service registrationfalse
USE_DEV_PROXYRoute API calls through a dev proxyfalse

🛠️ Commands

CommandDescription
bun run devStart dev server on port 14128
bun run buildProduction build
bun run startStart production server on port 14128
bun run generateStatic site generation
bun run previewPreview the production build
bun run typechecknuxt typecheck + tsc
bun testRun the test suite
bun run api-client:generateRegenerate the API client from the OpenAPI spec

🗺️ Project Structure

app/
├── app.vue                 # Root component
├── components/             # Auto-imported, organised by domain
│   ├── dashboard/          # Menus, search, notifications
│   ├── mail/               # List, folder view, detail, compose
│   ├── form/ · img/        # Shared form controls & branding
├── composables/            # Auto-imported logic
│   └── stores/             # Lightweight composable stores (not Pinia)
├── layouts/                # auth.vue (login) · default.vue (dashboard)
├── middleware/             # Global auth & URL-rewrite middleware
├── pages/                  # File-based routing
│   ├── auth/               # login · signup · forgot / reset password
│   ├── admin/              # user administration
│   └── (app)/              # mail, compose, settings, mail-accounts, apikeys
├── utils/                  # Helpers, base store, types
└── api-client/             # Generated API client — do not hand-edit

Note: Files ending in .gen.ts are generated from the API's OpenAPI spec. Regenerate with bun run api-client:generate rather than editing them by hand.

📦 The Delivr Project

RepositoryDescription
Delivr Web (you are here)The Nuxt 4 web client & PWA
Delivr APIThe Bun + Hono backend

📄 License

Licensed under the GNU AGPL-3.0.

Built with 💙 and Nuxt.

Delivr-Project/Delivr-Web

TypeScript

7

255 commits

updated Oct 3, 2026

See the code

See what people are saying

SourceMessageScoreDate

Delivr: A Modern Open Source Mail Client that actually works (r/selfhosted)

Hi everyone, for the past 10 months I've been working on Delivr (with help from a few great contributors), and today I'm releasing version 1.0.0. Why I built it: I wanted a self-hosted mail client that feels as good as Gmail. The open-source webmail clients I tried work, but most of them feel dated…

8

Oct 3, 2026

README

Delivr

Delivr Web

A Mail Client that actually Delivers

A fast, installable webmail client built with Nuxt 4 & Nuxt UI — your inbox, in a clean PWA that stays out of the way.


Nuxt Vue TypeScript Bun PWA License

API Backend →  •  Features  •  Quick Start  •  Configuration


✨ Features

  • 📥 Full mail workflow — browse folders, read threads, compose, and manage flags across multiple mail accounts.
  • 🗂️ Multi-account, multi-folder — switch between mail accounts and drill into any mailbox folder from a single dashboard.
  • 📎 Safe attachments & content — HTML is sanitised with dompurify and a remote-content policy keeps tracking pixels at bay.
  • 🔑 Accounts & API keys — sign in, reset passwords, manage security settings, and issue API keys from the UI.
  • 🛡️ Admin tools — user administration for instance operators.
  • 📱 Installable PWA — @vite-pwa/nuxt with auto-update, offline shell, and a native app-like experience.
  • 🌗 Dark by default — a focused, dark-first interface built on Nuxt UI 4 and Lucide icons.
  • 🔌 Type-safe API client — fully generated from the Delivr API's OpenAPI spec, so the frontend and backend never drift.

🧱 Tech Stack

LayerChoice
RuntimeBun 1.x
FrameworkNuxt 4.x (SSR)
UINuxt UI 4.x (Reka UI) + Lucide icons
LanguageTypeScript 6.x + Vue 3 + Vue Router 5
API Client@hey-api/openapi-ts (generated)
ValidationZod 4.x
PWA@vite-pwa/nuxt
Sanitizationdompurify

🚀 Quick Start

Prerequisites: Bun 1.x, and a running Delivr API instance.

# 1. Install dependencies
bun install

# 2. Configure your environment
cp example.env .env
#    → point DELIVR_API_URL at your running Delivr API

# 3. Start the dev server
bun run dev

Open http://localhost:14128 and sign in.

💡 Regenerating the API client: the frontend talks to the backend through a generated client. Keep the API running and up to date, then run bun run api-client:generate. Never hand-edit the *.gen.ts files.

🐳 Docker

Want to run the whole thing, API included? The Delivr API repository has a docker-compose.yml that starts both with one command. That's usually the easiest way.

If you already have an API running somewhere and just need the web client, grab the ready-made image:

docker run -d -p 14128:14128 \
  -e NUXT_PUBLIC_API_URL=https://api.example.com/v1 \
  -e NUXT_PUBLIC_APP_URL=https://mail.example.com \
  ghcr.io/delivr-project/delivr-web:latest

Or with Compose: DELIVR_API_URL=https://api.example.com/v1 docker compose up -d. To update, run docker compose pull && docker compose up -d.

Want to build it yourself instead? docker build -f docker/Dockerfile -t delivr-web . (or add --build to the Compose command).

You configure the image when you start it, so one build works for any setup:

VariableWhat it doesDefault
NUXT_PUBLIC_API_URLWhere the API lives, including /v1http://localhost:14123/v1
NUXT_PUBLIC_APP_URLThe address of this web clienthttp://localhost:14128
NUXT_PUBLIC_IS_SIGNUP_ENABLEDSet to true to show the sign-up link on the login pagefalse
PORTPort inside the container14128

Keep in mind that the API URL is used by your browser, not by the container, so it has to be an address you can open yourself. On the API side, DLA_APP_URL must point to this web client, or the browser will block the requests (CORS).

⚙️ Configuration

Environment-based configuration (see example.env):

VariableDescriptionDefault
DELIVR_API_URLBase URL of the Delivr API (v1)http://localhost:14123/v1
DELIVR_APP_URLPublic URL of this web apphttp://localhost:14128
DELIVR_ENABLE_SIGNUPAllow self-service registrationfalse
USE_DEV_PROXYRoute API calls through a dev proxyfalse

🛠️ Commands

CommandDescription
bun run devStart dev server on port 14128
bun run buildProduction build
bun run startStart production server on port 14128
bun run generateStatic site generation
bun run previewPreview the production build
bun run typechecknuxt typecheck + tsc
bun testRun the test suite
bun run api-client:generateRegenerate the API client from the OpenAPI spec

🗺️ Project Structure

app/
├── app.vue                 # Root component
├── components/             # Auto-imported, organised by domain
│   ├── dashboard/          # Menus, search, notifications
│   ├── mail/               # List, folder view, detail, compose
│   ├── form/ · img/        # Shared form controls & branding
├── composables/            # Auto-imported logic
│   └── stores/             # Lightweight composable stores (not Pinia)
├── layouts/                # auth.vue (login) · default.vue (dashboard)
├── middleware/             # Global auth & URL-rewrite middleware
├── pages/                  # File-based routing
│   ├── auth/               # login · signup · forgot / reset password
│   ├── admin/              # user administration
│   └── (app)/              # mail, compose, settings, mail-accounts, apikeys
├── utils/                  # Helpers, base store, types
└── api-client/             # Generated API client — do not hand-edit

Note: Files ending in .gen.ts are generated from the API's OpenAPI spec. Regenerate with bun run api-client:generate rather than editing them by hand.

📦 The Delivr Project

RepositoryDescription
Delivr Web (you are here)The Nuxt 4 web client & PWA
Delivr APIThe Bun + Hono backend

📄 License

Licensed under the GNU AGPL-3.0.

Built with 💙 and Nuxt.

Languages

TypeScript

50.8%

Vue

49.1%