Newsletter Platform
Subscriber management, monetization, analytics (Substack alternative)
Collaborators
philcal (project owner)
How do I use this software?
This software runs wherever suits you — you just need somewhere to host it. Pick the option that fits your team:
| Option | What it means |
|---|---|
| Self-hosting | Set up the environment and run it yourself, on your own infrastructure. |
| Tooltwist hosting | Tooltwist can host and run it for you. |
| Other providers | Find a host in the provider directory — or, if you already have a support company, we're happy to give them the tools to deploy the application for you. |
Licensing
This variant is open source — you're free to use it and modify it at no cost. Hosting and support arrangements are provided separately and are not covered by this licence.
Who can help me?
Plenty of people can help you get the most from this software — browse the provider directory. Some providers can host it for you, others can customise it to your needs, and others again offer technical support and a helpdesk.
Tooltwist can host and customise the software for you, and Twist Teams provides technical support services.
Already have a support provider? We're happy to give them the tools to fully support the platform.
Not sure who to ask? Feel free to .
How can I help?
If you would like to help develop or test this project, go to the Collaborators tab (after you log in) and request to join. Your help will be appreciated!
Read me first
A plain-language introduction to this software: who it is for, what it does, and what to do on your first day with it. No technical background assumed.
If you only read one thing, read Who this is for and What it does.
Who this is for
Someone who publishes a newsletter and wants to own it outright.
That covers a fairly wide range of people:
- Independent writers — one person, a mailing list, and some paying readers.
- Small newsrooms and editorial teams — a handful of people sharing the writing, sending and audience work.
- Brand, marketing and community teams — sending a regular letter to customers or members rather than running advertising campaigns.
- Anyone leaving a hosted platform — a publisher who currently pays a percentage of subscription revenue to Substack or similar, and would rather keep it.
The common thread is wanting the subscriber list, the payment relationship and the published archive to belong to the publisher rather than to a platform.
You do not need to be technical to use the software day to day. Getting it installed in the first place is a technical job — but that is a one-off, and it is the only part that is.
What it does
It runs a newsletter end to end.
You write a post. You choose whether it is free or for paying readers only. You send it to your subscribers as an email, and it also appears on a public web page that anyone can link to. People sign up, confirm, and eventually some of them pay. The software keeps track of all of that, tells you honestly how the writing performed, and takes care of the routine messages so you do not have to.
Concretely, it handles:
- Writing and publishing — drafts, scheduled posts, a published archive, and per-post control over whether a piece is free or paid.
- Sending — one post to one audience, with an explicit confirmation step because a send cannot be taken back.
- The audience — who subscribed, when, how, and whether they are still subscribed, along with the evidence that they consented.
- Money — paid tiers through Stripe, with no cut taken by this software.
- Measurement — what people clicked and how far they read, with an honest account of why open rates cannot be trusted.
- Automation — sequences that run themselves, such as welcoming a new reader over their first few days.
- Growth — where subscribers came from, and a referral scheme.
- A public home — an archive page, individual post pages, and feeds, on your own web address if you want one.
This is a core build. Everything above works, but it is deliberately plain: there is no branding, no house style, and no decoration. It is the working machinery, ready to be dressed.
The domain
If newsletter publishing is new to you, this is the shape of it.
A publication is the thing readers subscribe to — a title, a voice, a schedule. A person who signs up becomes a subscriber. Almost every jurisdiction requires you to prove they asked to hear from you, which is why sign-ups are usually confirmed by clicking a link in an email. That confirmed consent, and the record of it, is the single most valuable and most regulated thing a publisher holds.
Publishing an issue means writing it, then sending it to some or all of those subscribers. Once it has gone out it cannot be recalled — email has no undo. This is why serious sending tools make the moment of sending deliberately slow and explicit, and why this one asks you to type the number of people you are about to reach.
Money usually arrives through paid subscriptions: some posts are free, some are reserved for readers paying monthly or annually. Payments are handled by a payment company — here, Stripe — so that the publisher never touches card details.
The last thing worth understanding is why the numbers are difficult. Publishers traditionally judged a newsletter by its open rate. That measurement broke: Apple and others now fetch the invisible tracking image in an email before any human has seen it, so a large share of recorded "opens" are machines. Any tool that still leads with a single open-rate percentage is quietly misleading you. This one separates machine opens out, says so on the screen, and points you at clicks and reading depth instead.
Where it fits
The software does not run alone. It expects to sit alongside:
- An email delivery service. It does not run its own mail servers. It hands finished messages either to Resend or to any standard mail service you already use. You will need an account with one of them.
- Your sending domain. Mail providers only trust mail that is properly signed and authorised for the domain it claims to come from. That is a DNS configuration job, done once.
- Stripe, if you intend to charge. Readers are sent to Stripe's own payment pages, so card details never reach this software.
- An identity provider, for signing in to the dashboard. Sign-in is handled by an external provider rather than by passwords stored here.
- Optionally, your own systems. There is a small public interface for reading and changing subscribers from elsewhere, so a CRM or internal tool can stay in step. (Outgoing notifications are half-built — see the rough edges. For now, another system keeps in step by asking, not by being told.)
Your readers need nothing but an email address and a web browser.
First run
The very first thing to do is look at it with realistic data in it.
There is a self-contained preview package: one bundle containing the application, its database and a fully populated example publication called The Filament — around 420 subscribers, a dozen posts, ten completed sends, paying members at various stages, and a running welcome sequence. Nothing to install alongside it, nothing to configure, and no risk: it cannot reach a real inbox.
Start that, open it in a browser, and spend twenty minutes clicking around. The
exact command is in preview/README.md.
Three screens are worth looking at deliberately:
- Analytics, to see the open-rate caveat and the way machine opens are split out.
- A send confirmation, to see how the irreversible act is guarded.
- A single subscriber, to see what consent evidence actually looks like.
Then, when you understand the shape of it, set up a real installation. Do not put real subscribers into the preview package — it is built for evaluation and its passwords are published.
Setting up
A real installation is roughly six steps. The technical detail lives in
target/docs/self-hosting.md; this is what
each step is for.
- Install it somewhere. A server you control, or a hosted container service. This is the only genuinely technical step.
- Create your publication. Its name, its public address, and the name and address your email will come from.
- Connect an email service and prove you own your sending domain, by adding the DNS records your email service gives you. Until this is done your mail will land in spam. The send screen shows you whether it is verified.
- Connect Stripe, if you are charging, and create your tiers — what each one costs and what it includes.
- Bring your audience in. If you are moving from another platform, export your list from it and import it here. Import only people who genuinely subscribed: their consent evidence comes with them, and you may need it.
- Send yourself a test before you send anyone else anything.
A word of warning about steps 3 and 4: in this core build several one-off setup tasks — the sending domain, the paid tiers, signup forms and landing pages — are done through the programmable interface rather than through a screen. See the rough edges below. Day-to-day use is entirely in the dashboard.
For a stage or production environment there is a first-run initialisation procedure — see production setup.
Day to day
Most weeks look the same.
Write. Open Posts, start a new one, and write it. Give it a title and a body. Decide whether it is free or for paying readers. The revision number in the corner of the editor is a safety catch: if somebody else has saved the post since you opened it, your save is refused rather than quietly overwriting their work. (It is not a version history — there is no way to read an earlier draft back.) Leave it as a draft until you are happy, or schedule it for a date.
Send. When the post is ready it goes out as a campaign — one post, to one audience. The confirmation screen tells you how many people you are about to reach, which address it comes from, and whether your domain is properly authenticated. You type the recipient count to confirm. A send in progress can be paused; it can never be un-sent. The same post cannot be sent twice, so the campaign history is a complete and trustworthy record.
Watch what happened. A day or two later, look at Analytics. Judge the piece on clicks and how far people read. Treat the open figure as background noise.
Tend the audience. New subscribers arrive on their own and confirm themselves. You will occasionally need to look someone up — because they asked what you hold about them, or asked to be removed. Both are on the subscriber's own page.
Keep an eye on the money, if you charge. The monetisation screen shows who is paying, what is recurring, and which payments have failed and are inside their grace period before access is withdrawn.
That is the whole loop. Automations, growth and the AI screen are things you set up occasionally and then leave running.
Ongoing care
Things that are not weekly, but do matter:
- Back up the database. Your subscriber list, their consent evidence and your entire archive live in it. This is the single most important operational habit. Test that a backup actually restores.
- Watch bounces and complaints. Addresses that bounce hard are suppressed automatically. A rising complaint rate means people are marking you as spam, which will eventually damage delivery for everyone on your list.
- Prune quiet subscribers. People who have not opened or clicked in a year cost you sending money and drag your reputation down. The AI screen's churn ranking is a reasonable place to start.
- Re-check your DNS records if you change email provider or domain.
- Export your growth figures periodically if you report to anyone; there is a CSV export on the Analytics screen.
- Honour erasure requests promptly. Erasing someone destroys their address, their history and their consent record, but deliberately keeps their payment records in a form that no longer identifies them — because tax law requires the receipt and privacy law requires the name to go.
- Keep the software updated, particularly for security fixes.
A short glossary
| Term | What it means |
|---|---|
| Publication | The newsletter itself — its title, address and identity. One installation can hold several. |
| Subscriber | A person on your list, in one of four states: subscribed, awaiting confirmation, unsubscribed, or suppressed. |
| Suppressed | Blocked from receiving mail, usually because their address hard-bounced or they complained. Not the same as unsubscribing. |
| Double opt-in | Requiring a click on a confirmation email before someone counts as subscribed. This is what makes consent provable. |
| Consent evidence | The record of when and how someone agreed to hear from you — the timestamp, the originating form, and the address it came from. |
| Post | One piece of writing. May be free or restricted to paying readers. |
| Campaign | One post being sent to one audience. Cannot be repeated. |
| Tier | A paid level readers can buy, with a price and an interval. |
| Dunning | The polite chasing of a failed payment before access is removed. |
| Grace period | The window after a failed payment during which the reader keeps access. |
| Machine open | A tracking pixel fetched by a mail privacy service rather than by a person. Recorded, but never counted as readership. |
| Read depth | How far down a post someone actually scrolled. |
| Automation / sequence | A series of steps that runs itself when something happens — for example, welcoming a new subscriber. |
| Capture surface | Anywhere someone can sign up: an inline form, a pop-up, a slide-in, or a landing page. |
| Referral | A subscriber bringing in another, credited only once the new person confirms. |
| Frequency cap | A limit on how many messages one person can receive in a period, applied across both campaigns and automations. |
| Webhook | A message this software sends to another system when something happens. Registerable but not yet delivered in this build — see the rough edges. |
The other documents
| Document | Read it when |
|---|---|
| production-setup.md | You are preparing a real stage or production environment for its first use. |
preview/README.md | You want to run the self-contained evaluation package, or refresh its example data. |
target/docs/self-hosting.md | You are installing a real, permanent instance. |
target/docs/demo-data.md | You want to load realistic example data into an environment of your own. |
target/docs/security-review.md | You need to satisfy yourself, or someone else, about the security position. |
target/docs/accessibility-audit.md | You need to know how the interface performs for readers with access needs. |
docs/walkthrough-screenshots/ | You want a guided tour of the screens without installing anything. |
Who can do what
Every person with dashboard access holds a role on each publication: owner, admin, editor, or author. Whoever creates a publication becomes its owner. Editors and above can write, send, and change growth and automation settings; authors have a narrower reach.
Be aware: these roles are enforced by the software, but this core build has no screen for inviting colleagues or changing their roles. Adding a second person to a publication is currently a job for whoever installed it. If you need a team, this is one of the first things worth having built.
What ships in the preview, and starting fresh
The preview package contains an invented publication, The Filament, with about 420 subscribers across all four states, a dozen posts (some paid, one scheduled, one still a draft), ten completed sends with real engagement behind them, seventy-six paid subscriptions at various stages of health, a welcome sequence with live enrolments, and a set of capture surfaces and referrals.
None of it is real, and none of it can reach anybody. Every address uses a reserved domain that cannot receive mail, and the package is deliberately wired to a mail service that does not exist.
The example data exists so the screens look like a working publication rather than a set of empty tables. It is for evaluation only.
To start fresh, do not try to empty the preview package — install a real instance instead and follow production setup, which creates an empty publication properly. If you want realistic data in an environment of your own for training or demonstration, that is what demo data is for.
Common questions and gotchas
My open rate looks wrong. It probably is not — it is being reported honestly for once. Machine opens are excluded, so the figure is lower than the inflated number other platforms show. Judge posts by clicks and read depth.
Everything went to spam. Your sending domain is almost certainly not authenticated yet. The send confirmation screen tells you whether it is verified; if it is not, fix the DNS records before sending anything else.
Can I un-send? No. Nothing can. You can pause a send in progress, which stops the messages that have not gone yet, but delivered mail is gone.
Someone is on my list twice. They are not — addresses are de-duplicated. You may be seeing the same person in two different states, or two genuinely different addresses belonging to one human.
I imported a list and most of them are "awaiting confirmation". That is correct and deliberate. People you cannot prove consented are not treated as subscribed.
A referral has not been credited. Referrals count only once the referred person confirms their subscription, not when they sign up. Self-referrals, duplicates and suspected abuse are recorded as rejected rather than silently dropped — you can see them on the Growth screen.
The AI screen will not write me a draft. Drafting needs an AI provider configured for your installation; without one, that part stays switched off. The churn scoring beside it does not need a provider — it is calculated from your own records, and every score lists the reasons behind it.
Known rough edges in this core build:
- Reader pages come in English and French only. They are built to be translated and adding a language needs no programming — see adding a language — but only those two are supplied.
- Automation sequences are built as a list of steps, not on a canvas. You can say "send this, wait a day, send that". You cannot draw branching flowcharts.
- There is no drag-and-drop page designer. Landing pages are created by filling in a form.
Everything else that used to be listed here now works. Outbound notifications are delivered. Every setup task has a screen — including the publication's own name, which was the one that most obviously should never have needed a command. The confirmation rate on capture surfaces and the recipient count on campaign history both report real figures. And there is now a test that fails if anyone adds a capability to the programmatic interface without adding a screen for it, which is how this list got long in the first place.
Where to get help
This application was generated entirely by AI, and it is a core build — the functionality is there, the styling and branding are not, by design.
If you know your field and are comfortable working with AI tools, you can take it from here and shape it yourself. If you would rather not, or you want something more substantial built on top of it, visit the community at wbsp.ai. You will find people who can help, and you will also find other versions of this application and of others — one of them may already be closer to what you need than starting from here.
Suggestions and criticism are welcome there too.
Configuration
What this application asks for when somebody installs it. These are the questions, not anyone's answers — no values are held or shown here.
People sign in to this application. The hosting platform registers the sign-in for you when you install it, so there is nothing to set up yourself.
You will be asked for 5 things
smtp
Optional, and all or nothing — supply every part or skip the whole set. A half-configured integration is refused at install time.
- SMTP relay hostname
SMTP_HOST - SMTP password
SMTP_PASSWORD - SMTP username
SMTP_USER
stripe
Optional, and all or nothing — supply every part or skip the whole set. A half-configured integration is refused at install time.
- Stripe secret key
STRIPE_SECRET_KEYWhere to get this - Stripe webhook signing secret
STRIPE_WEBHOOK_SECRETWhere to get this
Supplied automatically — no typing needed
The hosting platform provides these when the application is installed, either by generating them or because it already knows them.
- AUTH_CLIENT_ID
- AUTH_CLIENT_SECRET
- AUTH_ISSUER
- AUTH_URL
- EMAIL_HMAC_KEY
- PUBLIC_BASE_URL