Self-hosted service
maathimself/mailflow avatar
maathimself/mailflow

MailFlow is a self-hosted webmail client that unifies IMAP accounts

A self-hosted, unified webmail client.

577 stars67 forksJavaScriptAGPL-3.0

At a glance

What is it?
MailFlow is a JavaScript webmail client from maathimself that connects several IMAP and SMTP accounts into one interface, with inbox categorisation, rules, a PWA shell, TOTP two-factor authentication and OIDC single sign-on. It suits a household or a small team, and its AGPL licence plus paid commercial tier is the part to read before deploying it.
Who is it for?
Adopt MailFlow if you have several IMAP accounts you want in one place, you are willing to run a container stack with a database and a cache, and you have a reason to keep your mail on hardware you control. Do not adopt it if your organisation cannot meet the AGPL-3.0 obligations for a hosted deployment, because the commercial licence is the only route in that case, and it is priced per installation.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One inbox for several IMAP accounts

MailFlow is described as a self-hosted, unified webmail client, and the core idea is that you connect multiple IMAP and SMTP accounts and manage them all in one interface. The topics list names the concept directly, with a unifiedinbox tag alongside email, emailclient and webmail. The application is JavaScript, the licence is AGPL-3.0 with a commercial alternative, the homepage is mailflow.sh, and the release history shows three 4.0 releases in October 2026, with v4.0.0 on the 15th, v4.0.1 on the 16th and v4.0.2 on the 19th, and the last push to the repository on 2026-10-20. The feature list explains what the unification buys you. A unified inbox merges all accounts into one view sorted by date, conversation threads group messages into reply chains with inline sent replies, folder navigation expands any account, and folder-structure sync means folders created or renamed in another client appear automatically on a configurable interval or on demand. Star, archive, delete and mark read or unread are synced back to IMAP, and the state changes are per-user configurable, with mark-as-read behaviour set to immediate on open, after a configurable delay in seconds, or manual.

Reading and writing: compose, rules, categories and unsubscribe

The daily use features are the ones that decide whether a mail client stays installed. Rich text compose is a WYSIWYG editor with font family, size, colour, highlight, tables, emoji, links, attachments, image resize handles and Excel table paste. Attachments work in both directions across all accounts, and reply, forward and compose use correct per-account SMTP routing. Inbox categories split incoming mail into automatic tabs for Primary, Newsletters, Social, Notifications and Other, using header detection and sender heuristics, with an AI reclassify button for the mistakes. A one-click unsubscribe button appears in the message pane for detected newsletters, and it either sends the request or opens the unsubscribe URL automatically. Inbox rules automate actions such as move, archive, delete, mark read and star based on sender, subject, recipient, headers, body or attachments, and a block list runs before the rules, moving mail from blocked senders to trash. Snooze holds a message until a chosen time and brings it back to the top of the inbox, and spam reporting is available from the context menu, the toolbar or bulk actions, with the feedback feeding into automated filtering in a future release. Full-text search runs across all connected accounts at once.

GTD labels that are really IMAP folders

The Getting Things Done feature is the most interesting design decision in the project, because it avoids the usual trap of storing workflow state in the application database. It is optional, off by default, and enabled per account under Settings, Categories, GTD. When it is on, a rail beside the message list groups threads into five states, and each state is backed by a real IMAP folder, so the labels sync to every other mail client and survive MailFlow itself. The states are Todo and Someday for things you need to act on, Watch and Delegated for things you are waiting on, and Reference for what you want to keep. The label clears itself once your latest non-draft reply is sent. Labelling is done from the keyboard, with t for Todo, w for Watch, d for Delegated, v for Reference, b for Someday and Shift+E for Done, all remappable in the keyboard shortcut settings, or from the context menu. Each state's folder name is configurable per account, and applying a state preserves every member in the target before removing the old copies. Inbox and ordinary labels remain intact, a state switch ends pending Undo windows while an initial classification still offers Undo where supported, and accounts with GTD off behave exactly as before.

Authentication: TOTP, OIDC, Microsoft 365 and the admin panel

Authentication is where a self-hosted mail client earns trust, and MailFlow has a substantial set of options. Two-factor authentication supports TOTP with any authenticator app, an email OTP fallback, and persistent device trust, with an admin-configurable enforcement policy. Single sign-on works through any OpenID Connect provider, with group claims from the identity provider able to be mapped to the MailFlow admin role, and optional RP-initiated logout so signing out also signs out of the provider. Microsoft 365 works through an Azure App Registration for work accounts, and personal Outlook.com through a device code flow. There is a user management layer with an admin panel, invite-only registration and invite emails, and a password recovery path through a recovery email address set in the profile settings. The AI assistant is separately gated, since it needs an OpenAI-compatible API provider or a ChatGPT Codex subscription, it can summarise threads, draft replies and answer questions about a message, and admins choose which users may use it. Other integrations include a Todoist connection that creates tasks from an email with a deep link back to the original message, and a CardDAV address book that exposes your MailFlow contacts to phone and desktop contact apps, with contact photos syncing and appearing as sender avatars.

The container stack: nginx, Caddy, Postgres and Redis

The repository is a multi-service deployment and the compose file shows the shape. The frontend service builds from frontend/Dockerfile and serves the React single page application while proxying the API, and the backend service builds from backend/Dockerfile and runs with NODE_ENV set to production on PORT 3000. The backend environment takes its session secret and its database coordinates from variables, with DB_HOST defaulting to postgres, DB_PORT to 5432, DB_NAME and DB_USER to mailflow, and REDIS_URL defaulting to redis://redis:6379. The frontend waits for the backend to report healthy before it starts, and its own healthcheck polls the UI every 15 seconds with a 5 second timeout, three retries and a 20 second start period. The default mode exposes HTTPS on APP_PORT and HTTP on APP_HTTP_PORT, with the HTTP port intended for use behind a reverse proxy that terminates TLS, and a production profile where Caddy handles TLS instead. There are three compose files in the tree, the default one, one for the https profile, and docker-compose.ghcr.yml for pulling prebuilt images, and the repository also carries a Caddyfile and a .nvmrc.

Ports, proxies and the reverse proxy warning

The environment configuration is where a deployment goes wrong, and the project's own comments are the best warning you will get. The instructions are to copy .env.example to .env, fill in the values, generate the TLS certificate or use the https profile for Let's Encrypt, and then run the compose command.

bash
# 1. Copy this file:   cp .env.example .env
# 2. Fill in the values below
# 3. Generate the TLS cert (see README) or use --profile https for Let's Encrypt
# 4. Run:              docker compose up -d --build

The access section sets APP_PORT to 443 for HTTPS and APP_HTTP_PORT to 80 for HTTP, with the note that the HTTP port is for use behind a reverse proxy that terminates TLS upstream, and that the proxy should forward X-Forwarded-Proto: https so session cookies work correctly. There is an NGINX_TLS setting to turn HTTPS off entirely when your own proxy terminates TLS. The longest comment in the file is about proxy counting, where the backend takes each client's address from a configurable number of hops back in X-Forwarded-For for the login rate limit and the login activity log. The default is one hop for nginx alone, or two with the https profile where Caddy is the second proxy, and the advice is to set 2 behind your own reverse proxy only if clients cannot reach the app's ports except through it.

Licensing, and what changes if you host it

The licence deserves a section of its own because the split is unusual. MailFlow is dual-licensed. Under AGPL-3.0 it is free for personal use, self-hosting and open-source projects, and if you modify and distribute it or host it you must publish your changes under the same licence. The commercial licence is 500 dollars per installation, one time, and is aimed at businesses or deployments where the AGPL obligations cannot be met, with a purchase link on the site. The stated intent is that personal self-hosting is free and always will be, and that the model exists to protect the project from commercial exploitation while keeping it freely available to individuals and families. Contributors are asked to read the Contributor License Agreement, and submitting a pull request means agreeing to its terms. The practical consequence for a team is straightforward. If you run MailFlow for yourself, nothing changes. If you offer it to colleagues inside one company, the AGPL analysis gets less comfortable, because the copyleft obligation attaches to network use rather than distribution, and that is the point of the AGPL. If you want to sell it, the commercial route is the only one that matches the licence terms.

Where MailFlow is the wrong choice

The limits follow from what a self-hosted mail client has to be. The first is that it is a server you operate, with a database, a cache, a reverse proxy in front of it and certificates to renew, and none of that is a weekend project for someone who just wanted one inbox. The second is that the client stores nothing itself in the way a hosted service does, since messages live in your IMAP server and MailFlow is a view over them, which means the feature set is bounded by what IMAP and SMTP offer, and a mail provider that throttles or restricts IMAP access will restrict MailFlow too. The third is the AI assistant, which needs an OpenAI-compatible endpoint or a Codex subscription, and if you turn it on, your mail content leaves your server to a model provider, which is a decision to make consciously rather than by leaving a default on. The fourth is the risk of a single account, since a unified inbox concentrates the blast radius of a compromise, and the two-factor and OIDC options exist precisely because that concentration is real. The fifth is the release cadence. Three 4.0 releases landed within five days in October 2026, which is fast for a system with this many moving parts, and a team that values predictability should read the roadmap on the site before pinning a version.

Editorial conclusion

Adopt MailFlow if you have several IMAP accounts you want in one place, you are willing to run a container stack with a database and a cache, and you have a reason to keep your mail on hardware you control. Do not adopt it if your organisation cannot meet the AGPL-3.0 obligations for a hosted deployment, because the commercial licence is the only route in that case, and it is priced per installation. Verify two things before you start: which database and cache you will run, since the compose file expects a Postgres instance and a Redis instance by default, and whether the default port exposure suits your network, since the documentation is explicit that Docker publishes the app ports on every interface and that host firewalls do not filter them. The practical first step is to copy .env.example to .env, fill in the values, and run docker compose up -d --build before you connect a single real account.

Frequently asked questions

What is MailFlow?

It is a self-hosted, unified webmail client that connects multiple IMAP and SMTP accounts and manages them in one interface, with a unified inbox, conversation threads, inbox categories, rules, a PWA shell and eleven interface languages. The site is mailflow.sh.

How do I install and configure MailFlow?

Copy .env.example to .env, fill in the values, generate the TLS certificate or use the https profile for Let's Encrypt, then run docker compose up -d --build. The stack is made of a frontend service serving the React app, a backend API, a Postgres database and Redis.

What licence is MailFlow under?

It is dual-licensed. AGPL-3.0 covers personal use, self-hosting and open-source projects, and requires you to publish your changes under the same licence if you distribute or host it. A commercial licence is 500 dollars per installation for deployments where the AGPL obligations cannot be met.

What does the GTD feature in MailFlow do?

It is an optional workflow, off by default and enabled per account under Settings, Categories, GTD, that groups threads into Todo, Watch, Delegated, Someday and Reference. Each state is backed by a real IMAP folder, so the labels sync to other mail clients and survive MailFlow itself, and threads are labelled from the keyboard with t, w, d, v, b and Shift+E.

Does MailFlow support single sign-on and two-factor authentication?

Yes. It supports single sign-on through any OpenID Connect provider, with group claims mappable to the admin role and optional RP-initiated logout, and two-factor authentication through TOTP with any authenticator app, an email OTP fallback and persistent device trust, with an admin-configurable enforcement policy. Microsoft 365 works through Azure App Registration.

What ports does MailFlow expose and how should they be bound?

The frontend publishes APP_PORT, which defaults to 443, and APP_HTTP_PORT, which defaults to 80. The documentation notes that Docker publishes these on every interface and that host firewalls do not filter them, so both should be bound to an address only your reverse proxy can reach, and the proxy hop count for X-Forwarded-For should match the number of proxies in front of the backend.

Official sources

  1. License: AGPL-3.0
  2. maathimself/mailflow on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/maathimself-mailflow.svg)](https://hysenlabs.com/projects/maathimself-mailflow)

Was this useful?