ihasmail

Comparison

ihasmail and Bulwark Webmail

We get asked this often enough that a straight answer is more useful than a diplomatic one. Both are self-hosted JMAP webmail clients for Stalwart. Both are AGPL. Both do mail, calendar, contacts and files. They are built on opposite instincts about how much a webmail should keep, and neither instinct is wrong — they suit different people. Here is what actually differs, so you can decide which one that is.

We are not neutral about our own product and it would be silly to pretend otherwise. What we can do is state their side from their own documentation rather than from our impression of it, mark the places where they have something we do not, and not read silence as absence. Where their docs do not cover something, this page says so instead of guessing.

Checked 2 September 2026 against their README at the commit dated 1 September 2026. Both projects move quickly; if something here has gone stale, tell us and we will fix it.

The one difference the rest follows from

Everything below is downstream of a single decision: how much the webmail keeps of its own.

ihasmail keeps nothing

There is no database, no config directory and no admin UI. Configuration is environment variables; your settings live in a settings.json inside your own JMAP Files store on Stalwart, so they follow the account rather than the install. With IMMUTABLE=1 the container runs read-only with no volume at all.

What that buys. Nothing to back up, migrate or restore, and an instance that can be deleted and recreated from the image and a handful of variables.

What it costs. Sessions live in memory, so every deploy signs everyone out. There is no admin dashboard, and a configuration change means restarting the container. Nothing can be customised per domain at runtime, because there is no runtime state to hold the customisation.

Bulwark keeps an admin layer

A setup wizard on first launch writes to an admin config directory, and an admin dashboard edits it afterwards. That directory is what makes the rest of their feature set possible: a plugin store, uploadable themes, per-domain branding, multiple JMAP servers picked by domain, and admin-enforced presets.

What that buys. An operator can change things without a redeploy, and an installation can be shaped for its users rather than for its image.

What it costs. The directory is durable state: it has to be preserved across upgrades and backed up with everything else, and two installs of one image are not the same thing until it is. Their docs note that environment variables also work and suit read-only infrastructure, with a variable overriding the admin-managed value and ADMIN_CONFIG_READONLY locking the directory after setup — so the cost is avoidable, at the price of not using the wizard the product is built around.

Put plainly: ihasmail has no admin dashboard and is not getting one, because Stalwart already has one. Stalwart's web admin is where accounts, domains, queues, TLS, Sieve at the server level and the rest are managed, and rebuilding a second one in the webmail would be duplicating a thing that already exists and works.

There is a security argument for the split as well as a tidiness one. Administration and reading your mail are different jobs for different people, and keeping them on separate surfaces means the administrative one can be locked down on its own terms — reachable only from inside the network, or on a different host, or behind separate credentials — without any of that touching the client every user signs into daily. A dashboard reached from the same origin as the mailbox is a larger surface to defend, and defending it well is work we would rather not have to be good at.

That is a trade rather than a free win, and the cost is real: anything ihasmail itself does needs an environment variable and a restart, and an operator who wanted one place to change everything has two. If you want a container you can delete and recreate with nothing to restore, that is the thing we optimised for and the reason the rest of this page reads the way it does.

Side by side

ihasmail Bulwark Webmail
Protocol JMAP only. No IMAP, POP3 or SMTP fallback JMAP, plus CalDAV subscriptions in the calendar
Stack Vite, React 19, TypeScript. The client is a plain static bundle that will sit on any static host or CDN; only the thin Node/Hono proxy behind it needs a runtime, and it holds no state Next.js 16 App Router, React 19, TypeScript, Tailwind v4, Tiptap editor
Persistence None. No database, no config directory; IMMUTABLE=1 runs read-only with no volume Admin config directory written by the setup wizard; optional encrypted settings data directory; can be locked read-only after setup
Configuration Environment variables only, plus an optional read-only settings policy file. Restart to change Setup wizard and admin dashboard, or environment variables, which override admin-managed values
Apps Mail, calendar, contacts, files, Sieve filters Mail, calendar, contacts, files, Sieve filters
Mail Three-pane, conversation view, virtualised list, Gmail-style shortcuts and search operators, scheduled send, undo send, multiple floating composers, templates, labels as IMAP keywords, read receipts, multiple identities Threading, unified inbox, cross-account view, full-text search, templates, S/MIME, a comparable shortcut set
S/MIME No. On the backlog, not built Yes, in mail
Calendar Month, week, day, agenda; recurrence-rule builder; drag to reschedule; free/busy lookup; iMIP invitations; colour categories synced as JSCalendar; message to event; iCAL import and export; read-only calendar subscriptions by URL; birthdays derived from contacts Month, week, day, agenda; recurring events; drag to reschedule; iMIP invitations; CalDAV subscriptions
Multiple servers One Stalwart at a time. Other people's calendars, address books and files appear through JMAP sharing, with per-collection accept and withdraw Several JMAP servers, picked by domain, with unified and cross-account views
Multi-tenancy Whatever Stalwart does. Multi-tenancy is a Stalwart enterprise feature and ihasmail does nothing that gets in its way — one instance serves a multi-tenant server as it comes Also a Stalwart concern, and separately their own multi-server support covers one client per server
Sign-in Stalwart credentials; signs in with a TOTP code where the account has two-factor on, though enrolling is not offered in the client yet; app passwords per device; sessions server-side with the upstream credentials sealed OAuth2 and OIDC with auto-discovery, an OAuth-only mode and automatic SSO, or basic auth; session credentials encrypted in an httpOnly cookie
Extensibility None. Single-purpose client, no plugin API Plugin system with bundled and marketplace plugins, a development directory, and uploadable theme packages
Theming Built-in palettes with light and dark modes and a separate accent, chosen per reader; no uploadable themes Uploadable theme packages, and themes distributed through the marketplace
Branding APP_NAME at runtime with no rebuild; logo, icons and favicons are static files a deploy can swap; accent colours are in the bundle and need a rebuild. One brand per instance, not per domain. The AGPL source-offer obligation is documented Per-domain overrides, custom logos, favicons and colours, login page customisation, build-time locale and base path
Languages English plus nine, all machine-translated and marked beta; about 620 CLDR locales for dates and numbers 27
Telemetry None, and nothing to opt into Anonymous, opt-in, off by default, documented as carrying no personal data
Licence AGPL-3.0-or-later AGPL v3, forked from an earlier MIT-licensed project whose attribution is preserved in their NOTICE
Stalwart version 0.16 or newer; 0.15 support frozen on a tag, with a migration tool Not stated in the material reviewed

What "no plugins" actually means here

The row above says ihasmail has no plugin system, which is true and reads worse than it is. There is no way to add a capability that is not in the build — but a good deal of what an extensible client gets extended with is already here as a switch. Bulwark publishes its plugins in a separate repository, which makes the two approaches unusually easy to line up. Their catalogue, and what stands in its place here:

Their plugin Here
external-mail-warningBuilt in, reader settingBanner on mail from outside the domains you list
external-link-warningBuilt in, reader settingInterrupts links to domains you have not trusted
reply-all-guardrailBuilt in, reader settingAsks again past a recipient count you pick
send-laterBuilt inScheduled send, where Stalwart has futureRelease
spam-scoreBuilt inReads the score the server already put in the headers
calendar-agendaBuilt inOne of the four calendar views
auto-tagSieve rulesRule builder or raw script, run server-side rather than in the client
gravatar, libravatarDifferent by choiceAvatars come from the contact's own photo, or generated initials. No third-party lookup, which would tell someone else who you correspond with
outlook-style-headersNot offeredOne header layout, not a choice
impersonation-noticePartlyThe outside-sender banner covers the common case; there is no display-name lookalike check
smimeNot builtOn the backlog
jitsi-meetNot builtVirtual locations on an event are shown and linked, but nothing is integrated
nextcloud-attachmentsNot builtAttachments go through JMAP Files on your own server
translateNot builtWould mean sending message text to a third party
quick-notesNot built
email-statsNot built

Six of their nineteen are things ihasmail does without being asked to, two are scaffolding for plugin authors rather than features, and six are genuinely absent here — S/MIME being the one people ask for. Two we have deliberately declined: avatar lookups and translation both work by sending something about your mail to somebody else's server, which is a fair trade for many people and not one we make on their behalf.

And the rest of the switches

Sixty-seven settings in all. A sample of what else is a toggle here, and who turns it on.

Built in Switched by
Outside-recipient confirmthe readerAsks before a reply leaves the organisation
Attachment reminderthe readerCatches "see attached" with nothing attached
Remote-image proxyoperator and readerIMAGE_PROXY for the instance, then a per-sender trust list
Read receiptsthe readerRequest them, and choose what to do when one is asked of you
Undo sendthe readerA window you set in seconds, or off
Templatesthe readerReusable bodies with placeholders
Labelsthe readerIMAP keywords with colours, so they follow you to other clients
Calendar subscriptionsthe readerRead-only calendars by URL
Birthday calendarthe readerDerived from contacts, stored nowhere
Palettes and accentthe readerLight and dark modes, chosen separately from the palette
Swipe actionsthe readerLeft and right, on touch
Sort presetsthe readerMulti-level, and scoped per folder if you want
App passwordsthe readerPer device, revocable
Defaults and locksthe operatorSeed any of the above for new accounts, lock them, or turn one on once for people already here

The trade is the honest one, and it runs both ways. Everything here arrived because somebody asked and it was built, which is slower than installing a plugin and means a capability nobody has asked for is simply absent. Their model adds things without a release; ours means there is nothing to install, sandbox, keep up to date or trust. If what you want is on these lists, it is a switch. If it is not, it is an issue and a wait — or the other client.

Which one to pick

Genuinely a question about your deployment rather than about the software.

Bulwark probably fits better if

  • you want an admin dashboard and a setup wizard rather than environment variables
  • you run more than one JMAP server, or want unified views across accounts
  • you need S/MIME today
  • you want different branding per domain from one instance, or plugins and themes
  • SSO through OAuth or OIDC is a requirement
  • you need a language we have not translated

ihasmail probably fits better if

  • you want a container with nothing to back up, migrate or restore
  • a read-only filesystem with no volume is a requirement rather than a preference
  • one Stalwart is all you point at — including a multi-tenant one, which ihasmail serves as it finds it
  • you would rather configure by environment variable and redeploy than click a dashboard
  • you want the client to be the only moving part

There is no third option being sold here. Bulwark is a good client built by people who chose differently, and on the questions that matter most to a lot of operators — SSO, plugins, several servers, S/MIME — they are ahead of us and we are not planning to catch up on all of it. If those are your questions, use theirs. If "what does this container keep?" is your question, that is the one we set out to answer.

Something wrong or out of date on this page? Open an issue — including if you work on Bulwark and we have misrepresented you.