This project (Mailgrep-web) is largely AI-generated and is in an experimental, beta-quality state. It may behave unpredictably, break in surprising ways, or expose sensitive data if used carelessly. Do not use this with production or irreplaceable email accounts. Always test on disposable mailboxes first.
Mailgrep-web is a small IMAP-based email analysis and cleanup tool built with Node.js, Express, and a vanilla HTML/JS front end.
It lets you:
- Connect to an IMAP inbox
- Fetch emails with live progress
- Group messages by sender or subject
- Search using plain text or regex
- Select and delete whole “folders” (groups) or individual emails
It’s designed for inbox bulk cleanup, especially when you have tens of thousands of messages in an ancient account.
- 🔗 IMAP connectivity to arbitrary servers (host, port, username, password)
- 📥 Chunked fetching with progress display (to avoid IMAP
Too long argumentissues) - 📂 Group by Sender or Subject with counts
- 🔍 Search with regex or plain text, with scope controls:
- All fields
- Email address
- Subject
- Body
- 🧠 Regex-aware search bar
/pattern/flagsstyle automatically treated as a regex- With “Regex” mode on, glob-like patterns (
*.com,*@*.de) are translated for you
- 🗑️ Batch deletion
- Delete selected emails within a group
- Delete all emails in selected “folders” (group keys)
- 🧵 SSE progress stream (
/api/progress) so the UI can show what the backend is doing
- Node.js 18+
- npm (or yarn)
- An IMAP account you are comfortable experimenting on (preferably not your only copy of anything important)
git clone https://github.com/grellis00/mailgrep-web.git
cd mailgrep-web
docker compose up -d --buildBy default the server listens on port 3000:
- Open: http://localhost:3000
You can view the backend logs with
docker logs mailgrep-web -fThe project layout looks like:
mailgrep-web/
├── Dockerfile
├── docker-compose.yml
├── server.js # Express + IMAP backend
├── package.json
└── public/
└── index.html # Front-end UI
In the web UI, fill in:
- Email address – your login/user
- Password – app password or mailbox password (depending on provider)
- IMAP host – e.g.
imap.gmail.com,imap.mail.yahoo.com, or your custom host - Port – usually
993for IMAP over SSL
Then:
- Click Connect.
- If successful, you’ll see a connected state and controls enable.
- Click Load Emails to use cached emails (if already fetched) or fetch from the server.
- Click Force Refresh to refetch everything from the server, bypassing the cache.
** LARGE INBOXES WILL TAKE A WHILE TO DOWNLOAD **
The backend:
- Opens the
INBOX - Determines message count
- Fetches messages in chunks, using sequence numbers and a carefully chosen BODY spec to avoid server quirks
- Parses each message using
mailparser - Exposes email data (from, fromEmail, subject, date, text, textFull) to the UI
- Email / Password / Host / Port
- Connect and Disconnect buttons
- Connection status indicator in the header
- Search scope – All / Email Address / Subject / Body
- Search input – supports:
- Plain text (case-insensitive)
- Regex literals:
/pattern/flags - Glob-like patterns in Regex mode (
*.com,*@*.de)
- Regex toggle – when on:
- Plain text like
*.comwill be translated into.*\.com
- Plain text like
- Group by – Sender or Subject
- Sort by – A–Z, Count, Date
- Load Emails and Force Refresh
The app groups emails into “folders” based on the selected group mode:
- Group by Sender → one folder per
fromEmail - Group by Subject → one folder per
subjectstring
You can:
- Select individual folders via checkboxes
- Select All Folders
- Delete all emails inside selected folders in one operation
Clicking a folder drills down into its emails:
- Each email shows:
- From
- Subject
- Date
- You can:
- Select individual emails
- Select all in that folder
- Delete selected emails
When you click “Back to Folders”, you go back to grouped mode.
When you delete emails or folders:
- The backend:
- Opens
INBOXread-write - Adds the
\Deletedflag to the UIDs in conservative chunks - Calls
EXPUNGE
- Opens
- The in-memory cache is updated so deleted emails no longer appear without a refetch
This is a hard delete from the IMAP server (depending on provider’s semantics). There is no undo.
Use only on mailboxes you have backed up or can afford to lose.
Below are some regex patterns that work well with Mailgrep-web.
Make sure Regex mode is enabled in the UI when using these.
Use Search Scope = “Email Address” and this regex:
^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.(?!com$|com\.au$|ca$|net$|org$|edu$)[A-Za-z0-9-]+$This matches things like:
promo@spam.ploffer@deal.trweird@domain.suexample@company.xyz
But does not match:
user@domain.comuser@domain.causer@domain.orguser@domain.netuser@domain.eduuser@domain.com.au
^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.de$Matches: hans@firma.de, info@amazon.de
^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.(ru|su|tr|pl)$Adjust the list as desired.
[A-Za-z]{6}\.comThis is mainly useful to confirm the regex engine is working as expected.
If you prefer glob-like patterns, you can type:
*@*.de→ matches addresses ending with.de*@*.ru→ matches addresses ending with.ru
The UI will translate these into proper regex internally when Regex mode is enabled.
- Credentials are sent to the backend to establish an IMAP connection.
- IMAP is assumed to be over TLS (port 993) with
tls: true. - Emails are stored only in memory on the server and not persisted to disk (in this version).
- There is no authentication layer around the web UI; anyone who can reach the server can try to connect to arbitrary IMAP accounts.
- Run this locally, not on a public server.
- Use test or throwaway email accounts whenever possible.
- Never store your real passwords in source control or shared config.
- Consider IMAP app passwords (e.g. for Gmail) instead of main passwords.
- Backend: Node.js + Express + imap-simple + mailparser
- Frontend: a single
public/index.htmlfile with inline CSS/JS - Long-running operations use Server-Sent Events via
/api/progress - Fetching uses sequence-number ranges and body-mode detection to deal with older IMAP servers and large, sparse mailbox histories.
The logic is intentionally conservative about chunk sizes to avoid IMAP errors like
UID FETCH: Too long argumentandInvalid BODY[...] section.
Treat this as “source available, no warranty” software.
Again: this is AI-generated experimental tooling. Double-check the code and behavior before trusting it with real data.