shouldivibecodeit

Should I vibe codeMailbird?

Build a Windows email client with unified inbox, local search, and simple integrations

A mail client is a browser you wrote for content sent by strangers, running beside your IMAP passwords.

?

Their verdict, the Premium (yearly) price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-05.

Can you build it?asked by canivibecodeit.com ↗KINDAweekend project · multi-day
?

Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.

Should you ship it?asked by usYOUR FUNERALit’ll work. then it’ll get you.

The honest answer

why the verdict is what it is

The other mail clients on this site fail on the sync engine, the credentialed daemon or the model with tool access. Mailbird's pitch is different and so is its failure mode: a unified inbox that also embeds other people's web apps in a sidebar. Both halves are the same sentence — you are rendering content authored by strangers inside a process that holds your mail credentials. Every message body is HTML and CSS written by whoever sent it, including the person who wants your session, and the shortest path from "make the email look right" to working code is a WebView with defaults nobody audited. Add remote image loading and you have accidentally shipped read receipts to spammers; add the integrations panel and three long-lived third-party sessions now share a cookie jar with your mailbox. The mail client is the reset link for everything else you own. It is an unusually bad thing to be the least-reviewed code on your machine.

What actually breaks

not "if". the specific failures.

  • The HTML renderer, which is the app's real input: message bodies are attacker-authored markup and CSS, delivered unsolicited, and the sanitiser you did not write is the only thing between them and your app
  • Remote content, loaded by default because that is how email looks right, which tells every sender when you opened their message, from roughly where, on which client — you have shipped tracking pixels a service to phone home to
  • The integrations sidebar, where embedding WhatsApp Web, Slack and a calendar as webviews puts three persistent third-party sessions in the same process and cookie store as your mail
  • Attachments: a client that writes to a temp path and hands the file to the OS handler is a delivery mechanism, and on Windows the mark-of-the-web flag is the mitigation nobody thinks to set
  • The local store and search index, which is every message you have in plaintext full-text form, in a directory your backup tool uploads on a schedule
  • Credentials, because supporting "any provider" means IMAP and SMTP passwords you can decrypt rather than scoped tokens you can revoke, and one of those accounts is probably your employer's
  • Microsoft's and Google's OAuth timetables, which retire authentication methods on their schedule — a client built around an app password stops working on a date you did not choose
  • The unified inbox's identity handling, where replying from the wrong account is one keystroke and cannot be recalled
  • IMAP itself: UIDVALIDITY resets, modified UTF-7 folder names, IDLE connections dropped after four minutes, and a different set of quirks per host
and then, at 3am

The reply box was the reason. Rendering message HTML in a locked-down view made the composer awkward, so the client got a full browser window with node integration switched on — the fastest way to let the editor talk to the app, and the default in the scaffold the agent started from. It worked, it shipped, nobody revisited it. Nine months later a supplier's invoice arrives with a stylesheet, a tracking pixel and a script tag, and the app renders it faithfully. The script has `require` in scope and a filesystem to itself: the SQLite store with every message in it, and the small encrypted credentials file beside it, whose key is in the same directory because that is where it got written. Nothing crashes. Nothing alerts. The only artefact is a mailbox that was read by someone who needed nothing but your address.

Is that you?

the verdict is a default, not a law

ship it if
  • It reads mail and renders it as plain text, and a real client stays installed for everything else
  • Every account authenticates over OAuth with tokens in the OS credential store, never a password your code can decrypt
  • Remote content is off by default and you have verified in a proxy that it really is off
  • Nothing else's session lives in the app — no embedded chat, no calendar webview, no sidebar of other people's web apps
  • It is one account, yours, on one machine, and the mailbox on the server remains the source of truth
don’t ship it if
  • Message HTML renders in a WebView with scripting enabled, or you cannot state which flags are set on it
  • Anyone else uses it, because their mail client is the recovery path for every account they own
  • It is the only copy of the mail — POP3 with delete-on-download makes your untested local database the archive
  • You built the integrations panel, which multiplies the number of long-lived sessions one bug can reach
  • It sends: an unattended send-later or a snooze that moves messages adds an irreversible operation to an app whose input is hostile

If you build it anyway

the checklist, then the prompt that enforces it

  1. Decide how message HTML is rendered before you write a single line of UI, and write the decision down. Sanitise server-side or in a worker, strip script, object, iframe, form and event handlers, and render in a view with scripting disabled and no access to the app's runtime.
  2. Block remote content by default with a per-sender allowlist, and route any content you do fetch through a proxy so the sender never sees the recipient's IP.
  3. Never open an attachment for the user. Save it, set the mark-of-the-web on Windows, and make them open it themselves from the file manager.
  4. Use OAuth wherever the provider offers it and put tokens in the OS keychain or credential manager. If a provider forces a stored password, write down what an attacker with the machine gets before you support it.
  5. Keep the credential store separate from the message database, with a key that is not sitting in the same directory as the thing it protects.
  6. Treat the server as the source of truth and the local cache as disposable. Rebuildable caches are a bug; irreplaceable ones are an incident.
  7. Do not embed third-party web apps. If you must, use separate profiles and partitions per integration, and accept that you are now maintaining a browser.
  8. Build read-only first: display, search, no mutations. Add mutations one at a time, each with a visible log of what it did.
the guardrail prompt
I am building a desktop email client with a unified inbox, local search and
integrations. Its real input is HTML written by strangers, and it runs beside
credentials for accounts I cannot afford to lose. Work in this order and push
back when I ask for something faster.

1. Before any UI, write down the rendering decision: how message HTML is
   sanitised, in what process it is displayed, which flags are set. Scripting
   off, no access to the app runtime, no host bridge in any view that shows a
   message. If I ask for a full browser window to make the composer easier,
   refuse and explain what a script tag in an invoice does.
2. Sanitise with a maintained library — DOMPurify or equivalent — stripping
   script, object, iframe, form, event handlers and remote CSS imports. Do not
   hand-roll a regex.
3. Block remote content by default with a per-sender allowlist, and proxy
   anything fetched so senders never learn my IP or read time.
4. Authenticate with OAuth wherever it exists and store tokens in the OS
   keychain. If a provider needs a password, say so explicitly and tell me what
   someone with my laptop can do with it.
5. Keep the credential store separate from the message database, with a key that
   is not in the same directory.
6. Build read-only first: fetch, display, search. No archiving, moving, deleting
   or sending until reading is correct.
7. Treat the server as the source of truth and the local cache as disposable.
   Never implement POP3 delete-on-download.
8. Attachments are saved, never launched. Apply the mark-of-the-web on Windows,
   and never infer a file type from its name.
9. Handle IMAP properly: UIDVALIDITY changes invalidate the cache, folder names
   are modified UTF-7, IDLE drops and must be re-established, Gmail is not a
   reference implementation.
10. Out of scope until I ask, and argue rather than stubbing: third-party web
    apps in a sidebar, send-later, snooze, read receipts.
paste this before you build — not after something breaks31 lines · 1949 chars

That one keeps you out of trouble. For the prompt that actually builds it, canivibecodeit.com has one.

their build prompt ↗

Or don’t build it

the boring option, and the way back out

just pay for it

Buy, and unusually here the price makes it easy: under six dollars a month per seat, or a one-off licence, for an application whose whole job is to safely render mail from people who wish you harm. What you are paying for is not the inbox layout — it is a rendering pipeline that has been attacked, an attachment policy someone thought about, a credential store that is not next to its own key, and updates when Microsoft retires another authentication method. Build the reader if you want to learn how IMAP works. Do not make it the thing you check your bank's reset emails in.

$5.75/mo is cheaper than your weekend.

your exit plan, if you already built it

Nearly free if you kept the mailbox as the source of truth. Uninstall, rebuild the cache in Thunderbird or Mailspring, and nothing is lost because the mail was never really in your app. Two things do not come along: anything you invented on top — tags, snoozes, local flags — which exists only in your schema unless you mirrored it into real IMAP keywords, and the credentials. Rotate every password the client ever held and revoke every OAuth grant, because the exit plan for software that stored mail passwords is not deleting a folder.

prior art · someone already did this
Mailspring

Actively maintained open-source desktop mail client with a native sync core, and a fair map of how much work a client really is.

DOMPurify

The HTML sanitiser you should be using before any message body reaches a view, maintained by people who attack this for a living.

Questions

Every mail client renders HTML. Why is that this entry's whole argument?

Because it is the part an agent will get wrong fastest and the part you will never test. Sync bugs announce themselves — mail is missing, threads look odd, something is obviously broken. A permissive renderer looks perfect: every message displays beautifully, right up to the one that was written to exploit it. It is also the only feature in a mail client whose input is chosen by an adversary who knows nothing about you except your address.

Is Electron the problem?

Not by itself — plenty of safe clients are Electron apps, and plenty of unsafe ones are native. The problem is the combination that generated code keeps reaching for: a browser window with host access enabled because it made the editor work, pointed at content from strangers, in a process that can read the message store and the credential file. Whatever the stack, the invariant is the same: the thing that renders a message must not be the thing that can reach your filesystem.

What about the integrations sidebar — is that not just convenience?

It is convenience with a cost that is easy to miss. Embedding WhatsApp Web, Slack or a calendar means hosting long-lived authenticated sessions for three more services inside your app. Unless each gets its own partition, a bug anywhere in your rendering path now reaches all of them, and your mail client has become the single process holding every session you use all day. If you want the sidebar, build it as separate windows with isolated storage, and accept that you are maintaining a small browser.

Why medium confidence on the verdict?

Because a genuinely read-only, plain-text, single-account client that keeps tokens in the keychain is a perfectly reasonable thing to build and would sit a whole band lower. The verdict is aimed at what people actually build, which is the unified inbox with rich HTML, integrations and eventually send-later. If you stay in the narrow version, take the SHIP IT conditions above seriously and this entry does not apply to you.

did you build it?

Every week, someone ships something they shouldn’t have.

New verdicts, the worst thing that landed in the trap, and the occasional incident report. No other email, ever.

also on the regret index
MimestreamDEMO ONLY

Your inbox is the reset link for everything else you own. It deserves better than your first sync engine.

AirmailYOUR FUNERAL

A custom action is a chained destructive operation bound to a swipe. You wrote it at 11pm. There is no undo.

Spark PremiumYOUR FUNERAL

Send later means a server that holds your mail password and presses send while you are asleep. Twice, sometimes.

last reviewed 2026-08-05 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice