Motivation
- As a software developer, I find traditonal email marketing/newsletter tools constrained and inflexible.
- I’m tired of paying monthly bills on inflated payment plans with artificial subscriber limits and feature availability. I do not understand why I must pay tens of dollars every month for a list of a few hundred subscribers and sending out an occasional newsletter.
- For some reasons, email providers like to change their product strategy and pricing, alienating their customers.
- When you become disappointed in your email provider, migrating to a better one is a lot of work. You need to migrate many things, including custom fields, templates, marketing automations, subscription forms, email archive, lead magnets, etc. Vendor lock-in is a thing!
- Since 2010, I created several simplified messaging systems (Email, SMS, Push) and integrated a SaaS project with Mailchimp. I have many unrealized ideas I’d like to implement someday.
- The idea of creating my own newsletter software emerged around 2018-2019, I started writing the first code for AWS in 2021, but quickly abandoned it due to a lack of time and motivation.
- In March 2022, Mailchimp destroyed two of my mailing lists without giving me a chance to retrieve my subscriber database. It also became impossible to pay for AWS, as Russian bank cards were no longer accepted abroad. This was the moment when push finally came to shove for me.
- By the way, Mailchimp (Intuit) has a practice of banning users without warning, not just Russians, which is why back in 2018, I developed an automatic backup tool called mailchimp-backup, thanks to which both of my mailing lists were saved from the monkey’s dirty hands. Many weren’t so lucky. For example, a well-known Russian author of books and courses on copywriting and editing, Maxim Ilyahov, had 8 years of work and a database of 180 thousand subscribers destroyed by Mailchimp. A translated screenshot is here.
- Initially, Mailgit was created for my own projects, but then I decided to offer it as an experimental product. This decision was influenced by the #ONCE concept from 37signals. I believe that in the context of deglobalization, countries striving for sovereignty, protecting supply chains and data, global SaaS projects will be under pressure, while commercial software with accessible code will get a new chance.
Now imagine the following:
- A flexible email newsletter/marketing tool, designed for those who are comfortable with programming and CLI tools, and find it inconvenient to click around in traditional products
- You can define your marketing campaigns or newsletters as code
- You only pay for the actual resources consumed - the cost for a list of a few hundred subscribers and sending out a newsletter once a month is close to zero.
- There is no vendor lock-in - the tool is self-hosted, you have access to its source code and have the rights to modify it as you want.
- You do not have to manage Linux virtual machines and configure SMTP servers to self-host the tool
What is Mailgit?
- It is a flexible email newsletter/marketing tool based on Markdown, Python and SQL
- You purchase a license, deploy the source code to the cloud yourself, and have full control over user data - this is not a SaaS with a monthly subscription.
- You pay only for what you use (besides the license cost) - the serverless architecture downscales to zero and grows according to your needs.
- The license is perpetual and includes one year of free updates, after which you can renew it or continue using the code as is.
- Email delivery (the most critical part) is handled by a transactional email provider of your choice.
- Out of the box, there is no branding, and everything is customizable, including a separate domain.
- You can deploy multiple instances of the tool for various mailing lists with different branding and domains.
- Flexible integration with other systems by writing code in Python.
- Instead of an API, you can work directly with the database.
- Comes with ready-made examples of email templates and campaigns.
Who is this product for?
- Technical specialists who want an exceptionally flexible email marketing system - you can modify and extend its source code as you see fit.
- Marketers with programming skills - instead of struggling with non-standard reports or segments, simply query the database directly. And if you can pair with a developer, the possibilities are endless!
- Founders of SaaS projects can save time on developing or integrating a mailing system. You can make Mailgit a part of your product and integrate it as tightly as you want.
- Owners of a large number of small mailing lists on different domains will be able to automate their deployment and configuration according to unified rules.
Next, you can jump straight to the offer or read about the system’s capabilities.
Capabilities
Available campaign types
- BroadcastCampaign - a one-off broadcast campaign
- SequenceCampaign - a sequence of emails with a specified interval between them
- SubscribedEventCampaign - triggered when a subscription form is submitted, sends a confirmation email and a push notification to the list owner
- ConfirmedEventCampaign - triggered when an email is confirmed, sends a push notification to the list owner
- UnsubscribedEventCampaign - triggered when someone unsubscribes, sends a push notification to the list owner
- ConfirmedEventIncentiveCampaign - triggered when an email is confirmed, sends an email with a lead magnet
Broadcast and Sequence can target the entire mailing list only. Additional segments can be implemented by writing YQL queries.
Other types of events can be implemented.
Available email providers
- SMTPSender - sending via the SMTP protocol (delivery status not implemented)
- MailgunSender - Mailgun.com
- DashaMailSender - DashaMail.ru
- SESSender - Amazon SES (delivery status not implemented)
- DevNullSender - a test provider for sending emails to an arbitrary URL
Console-based admin tool
There is a minimalistic admin UI written with Textual that works in a terminal:
![Terminal-based UI](/en/terminal-based-ui.png)
Sent messages log
View plain text and HTML versions of sent email messages:
![View email message](/en/message-view.png)
Push notifications
Get push notifications via Pushover or ntfy when someone subscribes or unsubscribes to your mailing list:
![Push notification](/en/push-notification.jpg)
Link tracking
Any links in an email body can be wrapped in a tracking tag:
{{ track_link("https://mailgit.app") }}
Clicking on such a link will generate an event, based on which a segment or trigger campaign can be created.
Subscription topics
In addition to the usual subscription status (yes/no), there is support for opt-in and opt-out topics, allowing subscribers to more flexibly manage what they are interested in receiving:
Subscribe to [{{ get_topic("promotion").name }}]({{ topic_subscribe_link("promotion") }}) topic if you want to hear more
Unsubscribe from [{{ topic.name }}]({{ topic_unsubscribe_link(topic) }}) topic, but continue receiving regular emails
There is also the concept of transactional topics for important messages that cannot be unsubscribed from.
Custom subscriber attributes
You can define your own Pydantic class with an arbitrary set of subscriber properties to use for segmentation.
Technical details
Architecture
- Define email campaigns by writing Python code, YQL (SQL) and Markdown, store them in a Git repository. No need to fiddle with GUIs.
- Templating using Jinja, with support for snippets, conditionals, extensions, and custom Markdown tags. HTML and plain text emails.
- Supports multiple transactional email providers, including custom ones.
- Deployed with Terraform, support multiple isolated environments (staging, separate mailing lists).
- Serverless hosting on Yandex Cloud - scales from zero, grows according to your needs, the amount of operations is minimal.
List of Yandex Cloud services used
![Yandex Cloud Services](/en/yandex-cloud-services.png)
Codebase stats
The amount of code is quite small:
─────────────────────────────────────────────────
Language Files Lines Blanks
─────────────────────────────────────────────────
Python 37 5496 368
HTML 20 1216 45
Terraform 13 1443 172
Markdown 7 184 40
YAML 3 277 4
Autoconf 1 13 0
CSS 1 11 1
Plain Text 1 105 0
SQL 1 66 4
gitignore 1 28 5
─────────────────────────────────────────────────
Total 85 8839 639
─────────────────────────────────────────────────
Estimated Cost to Develop (organic) $241 746
Estimated Schedule Effort (organic) 8,02 months
Estimated People Required (organic) 2,68
─────────────────────────────────────────────────
Limitations
- If you are not proficient in Python, HTML, Jinja, and Markdown, this tool is not for you.
- This is an experimental project in its early stages, with many changes expected, and updates may not be straightforward.
- The code quality is not perfect; some things need refactoring, and there are currently no unit or integration tests. The priority has been on quick deployment for my own projects.
- It only works in Yandex Cloud (but if you want to run a similar serverless email system on AWS or Azure and are willing to sponsor the development, see the offer).
- Load testing was done on 10,000 subscribers without issues, but there may be overlooked aspects, and larger databases may require optimizations or even significant modifications.
- Serverless architecture does not cap expenses (it depends on resource consumption and load); budget control mechanisms are planned but need development.
- Localization is currently only in English, with plans to add Russian. I have experience in product localization; this site, for example, is bilingual, and the subscription form already saves the browser’s language to the database. If you need another language immediately, you can replace all texts in the code and templates without full multi-language support.
- The development environment and deployment tools have only been tested on macOS. Adding Linux is easy, but if you need Windows, it will take time to implement. There are plans to create a repeatable Docker container with the development environment.
- The console UI communicates directly with the cloud and the database, with no access control support.
- There is no REST API yet; it will be designed if there are specific customers for it. There is no urgent need for it, as you can work directly with the database.
- There is no archiving or deletion of old data yet, but you can delete individual subscribers and campaigns, including email history.
- There is no pagination in the admin UI (but you can always make direct queries to the database).
- Due to the lack of triggers for FIFO queues in Yandex Cloud, race conditions are possible for event-driven campaigns when different events arrive simultaneously. Currently, these situations are avoided due to the relatively simple trigger campaigns available in the system.
- There are no reports yet, but you can write database queries.
- Documentation is absent; I plan to write it as I go. For now, you can rely on me and on the source code.
- Importing existing mailing lists needs to be developed individually, considering the data format.
- Email open tracking is not implemented and likely won’t be due to its inaccuracy. If you need it, you can implement it yourself.
- I do not plan to create a visual email editor or campaign builders. The entire concept is based on code. Learn Python, YQL, HTML, Jinja, and Markdown.
The offer
There is no formal offer yet, so here are some bullet points:
- The license cost for the code is not determined yet, but expect the early pricing to be around 700-1000 USD per year. If you need a cheaper option, I can recommend other projects like Listmonk or Sendy. Personally, this is not a startup for me, and I want straightforward and sustainable funding sources for further development.
- The license is perpetual and includes one year of free updates, after which you can renew it or continue using the code as is. It grants you the right to use and modify the code on an unlimited number of domains (there are no obfuscations or license checks in the source code). However, you cannot distribute or resell the product or its derivatives, nor can you lease it for free or for a fee. If you want something non-standard, let’s discuss individual licensing terms.
- I am willing to customize the product to your requirements at your expense, with me retaining all rights to the final source code (unless otherwise agreed), and you getting the right to use it under general terms with a personal discount on license renewal starting from the second year. If the customization is not included in the final product (due to its narrow use-case), you may need to sponsor its maintenance with product updates or maintain it yourself. The same applies to various custom integrations.
- If you want to launch a similar serverless email system on AWS, Azure, GCP, Tencent Cloud, Huawei Cloud, Alibaba Cloud, etc., and are willing to sponsor the development, let’s discuss it. This will be a project requiring several months of work. The same applies if you want to adapt the system for on-premise installation (e.g., with PostgreSQL or SQLite and a classic architecture).
- Since I run the project alone, the time available for support is limited. You can expect free help with product installation and a small number of support hours per year via email and calls if needed. Additional support is billed hourly.
- If you are proficient in Python and want to co-develop the project, let’s discuss collaboration options.
- My time zone is UTC+7, and I try to have weekends, so please take it into account.
Here’s how the process of obtaining the product will look like:
- You leave your email address in the form below (or simply email me ).
- We agree on a time for a call.
- During the call, we discuss all your questions, clarify use cases, and the corresponding capabilities of the email system.
- If after some time you decide the product is suitable for you, we agree on the price (as the product is in its early development stage, this is negotiable), and I send you an invoice (currently I can only sell to companies, not individuals).
- After the payment, you receive access to a private Git repository with the product code and access to a chat.
- During another call, I help you deploy the project to Yandex Cloud.