ihasmail

Gmail-class webmail
for Stalwart.

ihasmail is a JMAP-first web client: mail, calendars, contacts, files, filters and every other modern feature Stalwart Mail Server exposes — in one responsive app that works as well on a phone as it does on a desktop monitor.

AGPL-3.0-or-later Stalwart 0.16 & 0.15 JMAP only No database Installable PWA

Features

Everything Stalwart exposes, and nothing it doesn't

One app for mail, calendars, contacts and files. Where a capability is missing from the server, the feature that needs it steps aside rather than breaking.

Mail that behaves like Gmail

Three-pane layout with a drag-to-resize splitter, conversation view, virtualised infinite list, multi-select, drag & drop, context menus and the keyboard shortcuts your fingers already know — j/k, e, r/a/f, g i, /. Archive, label, move and delete all come with Undo.

Calendar

Month, week, day and agenda views over JMAP Calendars. Recurrence with a custom rule builder, time zones, reminders, attendees with real invitations and RSVP, free/busy lookup, and Outlook-style colour categories that sync as JSCalendar.

Contacts & files

Address books with groups, a full contact editor, vCard import/export and a letter index. Files browses JMAP FileNode storage with drag-and-drop upload, folders, rename and move.

Search you can actually type

Gmail operators work as written — from:, subject:, has:attachment, is:unread, label:, before:, larger: — with an advanced panel for when you'd rather click.

A composer that keeps up

Multiple floating composers, rich text with inline images and emoji, recipient chips autocompleting from contacts, the directory and recent recipients, multiple identities with HTML signatures, templates, undo send, and scheduled send that waits in the server's queue whether or not you're still online.

Sieve filters, built visually

Right-click a message and Filter messages like this… writes a Sieve rule pre-filled from the sender or list, creating target folders on the fly — and can apply it to the mail already sitting in the folder. There's a raw script editor with server-side validation underneath.

Private by default

Remote images are blocked until you say otherwise, with a per-sender allow-list and an optional proxy that fetches them without handing the sender your address. Mail renders sanitised inside a Shadow DOM. Read receipts are offered, never sent automatically.

Dates in your language

Every one of the ~620 locales CLDR knows about, each named in its own language and script, with your choice of date order and a 12- or 24-hour clock. Numerals follow the locale. Dates are entered through pickers in the same format, because browsers ignore the page's and use their own.

Installs like an app

A real PWA with a service worker, mobile layout, bottom tab bar and full-screen composer. Register it as your mailto: handler and the operating system will offer ihasmail wherever it asks for a mail client.

Screenshots

Light or dark, desktop or phone

The app follows your system theme by default, with a toggle in the top bar and a three-way choice in Settings — the same arrangement this site uses.

ihasmail inbox and conversation view in the dark theme

Inbox & conversation — dark

Three panes, collapsed conversation, labels with colours.

ihasmail inbox and conversation view in the light theme

Inbox & conversation — light

The same screen, following a light system preference.

The ihasmail reply composer

Reply composer

Identities, Reply-To, rich text, signature and quoted text.

ihasmail calendar, month view

Calendar

Month view, multiple calendars, colour categories.

ihasmail contacts view

Contacts

Address books, groups, and a full JSContact editor.

The ihasmail Sieve filter builder

Sieve filter builder

Also reachable from a message's right-click menu.

The ihasmail sign-in screen

Sign-in

Stalwart mailbox credentials, with TOTP where it's enabled.

ihasmail on a phone

Mobile layout

Bottom tab bar, drawer navigation, full-screen composer.

All screenshots are taken against the built-in mock server with sample data — no real mailbox involved.

Architecture

A client, not a second mail server

ihasmail holds no state of its own. Every mailbox, event, contact and file lives in Stalwart; the server in the middle exists to keep your password out of the browser and to speak JMAP on the page's behalf.

Browser

React SPA

JMAP client, push, and the zustand stores behind each view.

Your host

ihasmail server

Node + Hono. Session cookie in, sealed Basic auth out.

Upstream

Stalwart

The only source of truth. Mail, calendars, contacts, files.

What the backend is for

It authenticates against Stalwart's JMAP session endpoint and stores those credentials sealed with a key derived from the cookie secret — the server never persists a plaintext password, and the browser never sees one at all. From there it proxies /api/jmap, /api/blob, /api/upload, /api/events and /api/image, and serves the SPA under a strict CSP.

There is no database to install, back up or migrate. Stop the container and nothing has been lost but sessions.

Two generations of Stalwart

0.16 replaced the REST management API with JMAP registry objects, reshaped FileNode, split its rights up and moved configuration into the store. Where the two differ, ihasmail detects which server it is talking to rather than assuming.

  • Capabilities are negotiated, not presumed
  • Missing capability means the feature steps aside, not an error
  • Live push via EventSource, with polling as a fallback
  • A built-in mock Stalwart for development and demos

Stack

What it's built on

Small, current, and boring where boring is a virtue.

LayerChoiceWhy
web/ Vite + React 19 + TypeScript The SPA: src/jmap (client, push, types), src/store (zustand), src/views, src/lib.
server/ Node + Hono A thin proxy and session holder. Small enough to read in an afternoon.
protocol JMAP No IMAP, no POP3, no SMTP fallback path. One protocol, used properly.
storage Stalwart There is no second store. Nothing to keep in sync, nothing to reconcile.
sanitiser DOMPurify + Shadow DOM Sender HTML renders isolated from the app's own styles and scripts.
deployment Docker One container, configured entirely by environment variables.
licence AGPL-3.0-or-later Run it as a service for other people and they get the source too.

Security & privacy

Your password never reaches the browser

A webmail client sits between someone's mailbox and the open internet. These are the parts that decision touches.

In the app

  • Server-side sessions with per-session encrypted upstream credentials — no password in the browser, ever
  • httpOnly, SameSite cookies; CSRF header plus Sec-Fetch-Site checks
  • Strict Content-Security-Policy, sandboxed blob downloads
  • Sender HTML sanitised with DOMPurify inside a Shadow DOM
  • Remote images blocked by default, with an SSRF-safe proxy when you allow them
  • Login rate limiting and the usual security headers

Self-service, in Settings

Change your password, manage app passwords — a separate one per device, revocable on its own — and turn two-factor authentication on or off by scanning a QR code.

Enrolment codes are verified before anything is stored, so a mistyped key can't lock you out, and switching 2FA on moves the current session onto a dedicated app password rather than signing you straight back out.

Read receipts are worth calling out: when a sender asks for one, ihasmail offers to send a real RFC 8098 report — never automatically. Bulk mail, mailing lists and anything marked Auto-Submitted aren't offered one at all, and a receipt aimed somewhere other than the sender says so first.

License

AGPL-3.0-or-later, and why it changed

ihasmail was relicensed from GPL-3.0 to AGPL-3.0 in August 2026. Webmail is nearly always run as a network service rather than handed to anyone as a binary, and the AGPL's section 13 closes that gap: anyone running a modified ihasmail for other people has to offer them its source, which the GPL alone does not require.

That offer has to point at your source, not this one.

If you run a modified ihasmail, set SOURCE_URL to your own repository. The sign-in page and Settings › About both show it, so the people using your instance are told where the code they are actually running can be found.

Free software, no feature held back

There is no paid tier, no enterprise edition and nothing switched off behind a licence key. Copyright © 2026 LINUXexpert.org.

Read the licence

About

Built for one mailbox, then everyone else's

ihasmail exists because Stalwart is an excellent mail server with a genuinely modern protocol, and the web clients pointed at it were mostly IMAP clients wearing a JMAP hat. Building JMAP-first from the ground up turns out to change what the client can do: conversations, push, server-side scheduled send, free/busy lookup and Sieve round-tripping all stop being bolted on.

The current release is the 2.0 rewrite, in QA against a live Stalwart server. The earlier FastAPI/HTMX prototype has been removed entirely — only the logo survived.

A companion project, stalwart-migrator, handles the 0.15 → 0.16 upgrade: it checkpoints every phase, refuses to start on the things that cannot be fixed mid-migration, and validates the server afterwards. That path is treacherous by hand — the store is migrated in place with no way back, and Stalwart's own converter drops settings without saying so. The live instance made the jump in eight seconds of downtime with nothing lost.

ihasmail is written and maintained by LINUXexpert.org. Issues, feature requests and patches are all welcome on GitHub.