Files
SRCmail/README.md
T

7.7 KiB

Bulwark Webmail

Bulwark Webmail

A modern, self-hosted webmail client for Stalwart Mail Server.
Built with Next.js and the JMAP protocol.

License: MIT Version Docker


Screenshots

Inbox — three-pane layout with sidebar, email list, and viewer Dark mode
Compose with templates and autocomplete Settings
More screenshots
Login page Email viewer with thread expansion

Features

Mail

  • Read, compose, reply, reply-all, forward with rich HTML rendering
  • Threading — Gmail-style inline expansion with thread navigation
  • Draft auto-save with discard confirmation
  • Attachments — upload, download, and inline preview
  • Search — full-text with JMAP filter panel, search chips, and cross-mailbox queries
  • Batch operations — multi-select, archive, delete, move, tag
  • Color tags/labels and star/unstar
  • Virtual scrolling for large mailboxes
  • Quick reply from the viewer

Calendar

  • Month, week, day, and agenda views with mini-calendar sidebar
  • Drag-and-drop rescheduling, click-drag creation, edge-resize (15-min snap)
  • Recurring events with edit/delete scope (this / this and following / all)
  • Participant scheduling — iTIP invitations, organizer/attendee UI, RSVP
  • Inline calendar invitations in email viewer — auto-detect .ics, RSVP, import
  • iCalendar import with preview and bulk create
  • Notifications with configurable sound and alert persistence
  • Real-time sync via JMAP push

Contacts

  • Contact management with JMAP sync (RFC 9553/9610) and local fallback
  • Contact groups with group expansion and member management
  • vCard import/export (RFC 6350) with duplicate detection
  • Autocomplete in composer (To/Cc/Bcc)
  • Bulk operations — multi-select, delete, group add, export

Filters & Automation

  • Server-side email filters via JMAP Sieve Scripts (RFC 9661)
  • Visual rule builder — conditions (From, To, Subject, Size, Body…) and actions (Move, Forward, Star, Discard…)
  • Raw Sieve editor with syntax validation
  • Vacation responder with date range scheduling and sidebar indicator
  • Email templates — reusable, categorized, with placeholder auto-fill ({{recipientName}}, {{date}}, etc.)

Security & Privacy

  • External content blocked by default — trusted senders list for auto-load
  • HTML sanitization via DOMPurify with XSS prevention
  • SPF/DKIM/DMARC status indicators
  • OAuth2/OIDC with PKCE for SSO (Keycloak, Authentik, or built-in)
  • TOTP two-factor authentication
  • "Remember me" — AES-256-GCM encrypted httpOnly cookie (opt-in)
  • Security headers — CSP with per-request nonce, X-Frame-Options, Referrer-Policy
  • Newsletter unsubscribe (RFC 2369)

Interface

  • Three-pane layout — sidebar, email list, viewer
  • Dark and light themes with intelligent email color transformation
  • Responsive — desktop sidebar + mobile bottom tab bar
  • Keyboard shortcuts — full navigation without a mouse
  • Drag-and-drop email organization between mailboxes
  • Right-click context menus, toast notifications with undo, form validation with shake feedback
  • Accessibility — WCAG AA contrast, reduced-motion support, focus trap, screen reader live regions

Internationalization

8 languages: English · Français · 日本語 · Español · Italiano · Deutsch · Nederlands · Português

Automatic browser detection with persistent preference.

Identity Management

  • Multiple sender identities with per-identity signatures
  • Sub-addressinguser+tag@domain.com with contextual tag suggestions
  • Identity badges in viewer and email list

Quick Start

docker run -d -p 3000:3000 \
  -e JMAP_SERVER_URL=https://mail.example.com \
  ghcr.io/bulwarkmail/webmail:latest

Or with Docker Compose:

cp .env.example .env.local
# Edit .env.local — set JMAP_SERVER_URL
docker compose up -d

From Source

git clone https://github.com/bulwarkmail/webmail.git
cd webmail
npm install
cp .env.example .env.local
# Edit .env.local — set JMAP_SERVER_URL
npm run build && npm start

Development

npm run dev        # Start dev server (mock JMAP server included)
npm run typecheck  # Type checking
npm run lint       # Linting

Configuration

Edit .env.local:

# Required
JMAP_SERVER_URL=https://mail.example.com

# Optional
APP_NAME=My Webmail

All variables are runtime — Docker deployments can be configured without rebuilding.

OAuth2/OIDC (SSO)
OAUTH_ENABLED=true
OAUTH_CLIENT_ID=webmail
OAUTH_CLIENT_SECRET=              # optional, for confidential clients
OAUTH_ISSUER_URL=                 # optional, for external IdPs (Keycloak, Authentik)

Endpoints are auto-discovered via .well-known/oauth-authorization-server or .well-known/openid-configuration.

Remember Me
SESSION_SECRET=your-secret-key    # Generate with: openssl rand -base64 32

Credentials encrypted with AES-256-GCM, stored in an httpOnly cookie (30-day expiry).

Keyboard Shortcuts

Key Action
j / k Navigate between emails
Enter / o Open email
Esc Close / deselect
c Compose
r / R Reply / Reply all
f Forward
s Star
e Archive
# Delete
/ Search
? Show all shortcuts

Tech Stack

Framework Next.js 16 with App Router
Language TypeScript
Styling Tailwind CSS v4
State Zustand
Protocol Custom JMAP client (RFC 8620)
i18n next-intl
Icons Lucide React

Why Stalwart?

Stalwart is a mail server written in Rust with native JMAP support — not IMAP/SMTP with JMAP bolted on. It handles JMAP, IMAP, SMTP, and ManageSieve in a single binary. Self-hosted, no third-party dependencies.

Contributing

See CONTRIBUTING.md for guidelines.

Roadmap

See ROADMAP.md for planned features and current status.

License

MIT