Notifuse: a self-hosted newsletter and transactional email platform in Go
Open-source, self-hosted newsletter, email marketing and transactional email platform. Visual MJML editor, Liquid templating, 7 sending providers.
At a glance
- What is it?
- Notifuse bundles a visual MJML editor, Liquid templating, seven sending providers and cookieless web analytics into one PostgreSQL-backed Go service. It is a real alternative to Mailchimp for teams willing to run their own infrastructure, with the licensing question left open in the repository metadata.
- Who is it for?
- Adopt Notifuse if you already run PostgreSQL, want one service for campaigns and transactional mail, and prefer MJML templates you control over a SaaS editor. Do not adopt it if you need a permissive licence confirmed in advance, cannot run PostgreSQL 17, or expect a managed sending reputation.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 14 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap Notifuse fills between Mailchimp and a bare SMTP relay
Sending email is easy. Sending it with a subscriber list, a template editor, per-contact state, and open and click tracking is the part teams usually rent. Notifuse packages that layer and runs it yourself. The README positions it as "the open-source alternative to Mailchimp, Brevo, Mailjet, Listmonk, Mailerlite, and Klaviyo, Loop.so, etc." The target user is a team that already operates infrastructure and resents per-contact pricing. It is not aimed at someone who wants a drag-and-drop tool and no server. The feature set spans three areas that are usually separate products: campaign management with A/B testing, a transactional REST API, and a web analytics module called Staminads that the README says is merged into Notifuse and runs entirely on PostgreSQL. That last point is the clearest statement of intent. The project would rather add a table than add a service.
How the Go backend and React console fit together
The repository splits into a Go backend and two React frontends. The backend follows what the README calls clean architecture: domain entities under internal/domain, business logic under internal/service, data access under internal/repository, and API handlers under internal/http. PostgreSQL is the only datastore, queried through the Squirrel query builder. The console is React, Ant Design and TypeScript in console/, and a separate embeddable notification widget lives in notification_center/. The Dockerfile builds each frontend in its own Node 22 Alpine stage before compiling the Go binary, and the web analytics browser SDK is built as a third stage and embedded into the Go binary. That is why the SDK is served from your own instance at /na.js rather than a CDN. Automations are graphs: each has a single trigger as its root and nodes typed delay, email, branch, filter, add_to_list, remove_from_list, ab_test, webhook or list_status_branch. Every enrollment carries its own status (active, completed, exited, failed) and current node, with per-node history. That per-contact state is the design decision that makes exit_on_reply and once-versus-every_time enrollment possible.
Installing Notifuse with Docker Compose and sending a first campaign
The repository ships compose.yaml, which builds the API from the local Dockerfile and exposes ports 8081 and 587 on the host. The database defaults assume a host named postgres, a database named notifuse_system, and the user postgres. The compose file warns that values containing # must be quoted in a .env file, so a password like mypass#word123 becomes DB_PASSWORD="mypass#word123".
git clone https://github.com/Notifuse/notifuse.git
cd notifuse
docker compose up -dOnce the containers are up, the README says an interactive setup wizard handles first deployment and configuration, and that settings such as ROOT_EMAIL, API_ENDPOINT and the SMTP variables can either be entered there or set as environment variables. The compose file leaves those commented out, so the wizard is the default path. For a local build without Docker, the Makefile expects CGO because of V8: make build runs CGO_ENABLED=1 go build -o bin/server ./cmd/api, and make build-static prints a note that static builds are not compatible with V8.
make buildAfter signing in, the flow described in the README is: create a workspace, add a sending provider, import contacts, then build a campaign in the visual editor. The provider list is Amazon SES, Mailgun, Postmark, Mailjet, SparkPost, SendGrid and SMTP. Templates use Liquid, so a first name is written as {{ contact.first_name }}. Contacts can be seeded from the sample files in samples/, including samples/sample_contacts.csv and samples/1000_contacts.csv.
Seven providers, one PostgreSQL requirement, and the V8 build constraint
The provider list is a genuine strength: SES, Mailgun, Postmark, Mailjet, SparkPost, SendGrid and plain SMTP cover most deliverability strategies, and switching providers is a configuration change rather than a migration. The constraints are less comfortable. PostgreSQL 17 or newer is required, and the README explains that the shipped compose file stays on 17 because upgrading a major version needs pg_upgrade and PostgreSQL 18 changed its data directory layout. That is an honest note, but it means the database version is pinned by the application, not by your platform team. The second constraint is CGO. The Makefile states that static builds with CGO_ENABLED=0 are not compatible with V8, which the project uses for Liquid rendering. A single static binary is therefore not an option; you ship a container or a dynamically linked binary. The third is operational: web analytics sessions are kept for as long as you keep them. Monthly partitions such as web_sessions_y2026m08 are created automatically, and the README describes expiring old data as a deliberate DROP TABLE on the partitions you no longer want. Nothing prunes for you. If you enable web analytics and never drop partitions, the database grows without limit.
Where Notifuse is the wrong tool
Notifuse is not a fit if you want a permissive licence confirmed before you build on it. The repository metadata reports the licence as NOASSERTION, which means GitHub could not classify it automatically. The repository does contain both LICENSE and LICENSING.md, and the compose file references a NOTIFUSE_LICENSE_KEY that is optional and, when unset, means the free tier. The integration test documentation is more explicit: without the licdev build tag the binary trusts only the release signing key, the server degrades to the free tier, and suites that create a fourth workspace or sign in through SSO fail on a 402. So the free tier appears to be bounded by workspace count and SSO, and the commercial terms live in files this review has not read. Anyone evaluating Notifuse for a commercial product should read LICENSE and LICENSING.md directly rather than infer from the README's "open-source" framing.
The second mismatch is scale of operations. Notifuse gives you templates, lists and tracking. It does not give you sending reputation, IP warming, or a deliverability team. You still need a provider account and the discipline to use it. Teams that want someone else to own inbox placement should stay on a hosted platform. The third mismatch is analytics volume: the README points heavy-traffic installs at AlloyDB Omni through compose.alloydb.yaml for columnar acceleration with zero schema changes, which is a reasonable escape hatch but also an admission that plain PostgreSQL has a ceiling for dashboard queries.
How Notifuse differs from Listmonk and from a hosted API like Resend
Listmonk is the closest comparison and appears in the README's own list of alternatives. Both are self-hosted and PostgreSQL-backed, and both target newsletter senders who want to own the list. The difference in approach is in the authoring layer. Notifuse ships a visual MJML editor with real-time preview and Liquid templating, and it carries a transactional REST API alongside campaigns. Listmonk's model is a campaign and list manager with templates. If your workload is mostly one-off transactional sends triggered by application events, the Notifuse API and the notification center widget are the reason to pick it; if you only send a weekly newsletter, the extra surface is weight you maintain for nothing. Against a hosted API such as Resend, the difference is inverted: Resend gives you an API and takes the deliverability problem, while Notifuse gives you the whole console and hands the deliverability problem back. The README lists Notifuse as a "self-hosted Resend alternative" in its own topics, but the honest framing is that Notifuse replaces the console and the list, not the sending infrastructure. You still connect SES, Mailgun, Postmark, Mailjet, SparkPost, SendGrid or SMTP underneath.
Maintenance, releases and what a version number costs you
Release cadence is fast. The repository shows v39.0 on 2026-08-29, v39.1 on 2026-09-01, and v40.0 on 2026-09-05, with the last push to main on 2026-09-08. Three minor or major releases in eight days means the project is moving quickly and that pinning a version is the only sane deployment strategy. It also means upgrade notes matter: the v39.0 release is labelled "Zapier + new permissions", which suggests schema or permission changes that a self-hosted operator has to apply. The repository has a CHANGELOG.md and a Makefile with a test-migrations target, so migrations are a first-class concern, but the README does not document a rollback path. Verify that before you upgrade in place. On the operational side, the make targets that matter for a fork are test-integration, which requires both the integration and licdev build tags and a 20 minute timeout, and test-unit, which runs the internal and pkg packages with the race detector. A team that patches Notifuse should be able to run those before deploying. On licensing, the repository contains CLA.md and LICENSING.md alongside LICENSE; the presence of a contributor agreement usually signals a project that intends to keep relicensing options open. That is worth reading before you contribute code you care about. This is not legal advice, and the licence identifier in the repository metadata is unresolved.
Editorial conclusion
Adopt Notifuse if you already run PostgreSQL, want one service for campaigns and transactional mail, and prefer MJML templates you control over a SaaS editor. Do not adopt it if you need a permissive licence confirmed in advance, cannot run PostgreSQL 17, or expect a managed sending reputation. Before committing, read LICENSING.md and LICENSE together, check env.example for the NOTIFUSE_LICENSE_KEY behavior, and confirm whether the free tier covers the number of workspaces and SSO you need.
Frequently asked questions
What are some open-source alternatives to Mailchimp?
Notifuse is one: the README describes it as an open-source, self-hosted emailing platform and names Mailchimp, Brevo, Mailjet, Listmonk, Mailerlite, Klaviyo and Loop.so as the products it positions itself against. It runs on PostgreSQL and supports Amazon SES, Mailgun, Postmark, Mailjet, SparkPost, SendGrid and SMTP as sending providers.
What does notification email mean in Notifuse?
Notifuse separates campaign email from transactional email. The README describes a transactional REST API for automated delivery and a Notification Center, an embeddable widget in notification_center/ for customer notifications, both running on the same PostgreSQL database as campaigns.
Is a push notification the same as an email in Notifuse?
The repository does not describe push notifications. Notifuse sends email through seven providers plus SMTP, and its notification surface is the embeddable Notification Center widget, which is a web component rather than a mobile push channel.
What is a service notification email in Notifuse?
The README does not use the term service notification email. The closest documented mechanism is the transactional API for automated email delivery, which is separate from campaign sends and can be driven by application events.
Official sources
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.
[](https://hysenlabs.com/projects/notifuse-notifuse)