Project Brief
I needed to send personal emails to a lot of people at once. Not spam. Just real messages to people who had signed up, each one with their own name in it.
I looked around and didn't love what I found. So I built my own tool. It's called Bulk Mailer.
Here's how it works. You open the app and drop in an Excel or CSV file with names and emails. You write your email and add little tags like {{name}}. The app swaps each tag for the right person's name. You send yourself a test first. Then you hit send.
When it's done, you get a full report. It shows who got the email and who didn't. You can save that report as a CSV or Excel file.
The best part? It all runs on your own computer. It works on both Mac and Windows. There's no server and no online database. I never see your data. The only thing that leaves your computer is the email you send.
Today I'm making it open source under the MIT license. That means it's free for anyone to use, read, copy or change. You can download the app or look at every line of code on GitHub.
- GitHub: github.com/the-mihir/bulk-mailer
- Download: Latest release
What Problem Does It Solve?
Sending a few hundred personal emails sounds easy. But when I tried it, I found only two choices, and I didn't like either one.
Choice one: a big email marketing service. These work well. But you pay every month. You have to upload your contact list to someone else's website. And you get tons of features you'll never use. I just wanted to send one message to my list with each person's name in it.
Choice two: write a quick script. This is cheap. But things go wrong. The internet drops. The email service tells you to slow down. Your laptop falls asleep halfway through. Then you're stuck with a scary question: Who got the email? And if I run it again, will some people get it twice?
I wanted something in the middle. So Bulk Mailer sends emails in safe, small groups. It slows down when it needs to. It tries again when something fails. It picks up where it left off if the app closes. And it makes sure nobody ever gets the same email twice. All of this happens in a simple app that keeps your list and your key safe on your own computer.
Key Features
- Easy Excel and CSV import. Drop in a
.xlsx,.xlsor.csvfile with up to 10,000 rows. The app finds the name and email columns by itself. It cleans up the emails and sorts every row into three tabs: Valid, Invalid and Duplicate. You see the problems before anything is sent. - Make every email personal. Use
{{name}},{{email}}or any column from your sheet. For example, a column calledCompany Nameturns into{{company_name}}. A live preview shows you exactly what each person will see. - Send a test first. Send a
[TEST]copy to yourself. Check that it looks right and doesn't land in spam. - Safe sending. Emails go out in groups of 100. The app keeps a steady speed so it doesn't get blocked. If a group fails, it tries again. Each group has a special ID, so trying again never sends a double email.
- Pause, resume or cancel anytime. The app saves its progress after every group. If it closes by accident, you can open History and continue from the exact spot where it stopped.
- Smart about errors. If the email service says "slow down," the app waits. If the internet drops, it waits a bit longer each time and tries again. If you hit your daily limit, it pauses so you can finish tomorrow. If your key is wrong, it stops right away and tells you how to fix it.
- Clear reports. Every person gets a status and a tracking ID. Save the report as CSV or Excel. If some emails failed, you can resend only those.
- Locked and private. You make a password the first time you open the app. After 5 wrong tries, it locks for 5 minutes. It also locks itself when you're away. Your email service key is locked away by your computer's own security system, and the app never shows it again.
- Light and dark mode. Pick the one that's easier on your eyes.
Tech Used (and Why)
Here's what I built it with, and why I picked each tool:
- Electron 44 + electron-vite: Electron lets me build one app that works on both Mac and Windows. electron-vite makes coding fast, because I see my changes right away.
- React 19 + TypeScript: React builds the screens. TypeScript checks my code for mistakes before the app even runs. That saves me a lot of bugs.
- Tailwind CSS v4 + shadcn/ui: These helped me make a clean, good-looking design without starting from zero.
- Zustand, react-hook-form and Zod: Zustand remembers what's going on in the app. react-hook-form handles the forms. Zod double-checks every piece of data so bad input can't sneak in.
- SheetJS: It reads Excel and CSV files, even messy ones.
- Resend: This is the email service that actually delivers the emails. It can send many emails in one go, and it helps prevent double sends. I didn't have to run my own mail server.
- Vitest + Playwright: These are my testing tools. Vitest checks small parts of the code. Playwright clicks through the whole app like a real person would, using a fake email service.
- GitHub Actions + electron-builder: When I release a new version, GitHub runs all my tests. Then it builds the Mac and Windows installers for me.
How I Kept It Safe
This app holds your email key and your contact list. So I took safety very seriously. Here's what I did:
- The part of the app you see can't touch your files or the internet directly. Only the hidden "back end" part of the app can do that.
- Only the app's own window can ask the back end to do things. You must be logged in first. And every request is checked with Zod before it runs.
- Your email key is locked with your computer's built-in security (Keychain on Mac, DPAPI on Windows). The screen never gets to see it.
- The email preview runs in a locked box, so nothing inside an email can harm the app.
- Data from your spreadsheet is cleaned before it goes into an email. That way, a sneaky value in a cell can't break the email or add hidden settings to it.
Why People Need It
- No monthly bill. You only pay the email service for what you send. The app is free.
- Your data stays with you. Your contact list lives on your computer, not on someone else's server.
- You can trust it. It picks up after a crash, resends only the failed emails, and never sends doubles. Those are the things quick scripts usually get wrong.
- You get proof. The report tells you exactly what happened to every single email.
- It's open. Anyone can read the code and see how it works. If you want to use a different email service, the sending code is all in one file, so it's easy to change.
Who Is It For?
- Small businesses and agencies that want to send updates, news or payment reminders to their own customers.
- Schools, training centres and event planners that need to email students, parents or guests.
- Founders and makers who want to tell their sign-up list about a launch or a new feature.
- Developers who want to learn from a real project built with Electron, React and TypeScript.
Please only email people who said yes to hearing from you. If you send to lists you bought or copied from the internet, your domain can get blocked and your email account can get shut down.
What Purpose Does It Serve?
Bulk Mailer fills the gap between a shaky script and an expensive marketing tool. It's small, simple and does one job well. It sends personal emails to a list you already have, safely, right from your own computer.
Why I'm Making It Open Source
I built this to fix a real problem I had. And I believe that any app holding your email key and your contacts should be something you can check for yourself. You shouldn't have to just trust it.
With the MIT license, anyone can use Bulk Mailer for free, see exactly how it handles their data, and help make it better.
Want to help? Issues and pull requests are welcome on GitHub. I just ask one thing: please keep the app safe. Keep the screen side away from files and the internet, and check every new request with Zod.
If this tool helps you, I'd love a ⭐ on GitHub. It really means a lot.
Links
- GitHub repository: github.com/the-mihir/bulk-mailer
- Download (Mac & Windows): github.com/the-mihir/bulk-mailer/releases
- Report a problem: github.com/the-mihir/bulk-mailer/issues
