shouldivibecodeit

Should I vibe codeHeartbeat?

Run a private community with channels, events, courses, and lightweight workflows

A forum can be down for an hour. A chat room that is down for an hour is a Discord server by lunchtime.

?

Their verdict, the Build price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-04.

Can you build it?asked by canivibecodeit.com ↗KINDAweekend project · multi-day
?

Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.

Should you ship it?asked by usYOUR FUNERALit’ll work. then it’ll get you.

The honest answer

why the verdict is what it is

Heartbeat is not a forum with a chat tab bolted on — the chat is the point, and that changes what a bug costs. Live rooms and channels mean an outage is visible within thirty seconds and self-solving: somebody drops a Discord invite, and the conversation has a new address by the time you have found the connection limit you never configured. Underneath the chat sits a member directory, which is the most valuable object in the product and the one a generated app will happily paginate for anyone holding a session — a tidy list of everyone who joined you, with roles, links and usually emails. Add self-hosted course video and paid tickets and you are also running a CDN and a box office. An agent will build all of it, and most of it will work. The parts that don't are the parts that are load-bearing on a Sunday evening.

What actually breaks

not "if". the specific failures.

  • The member directory, which is a roster of everyone who joined — names, roles, links, usually emails — behind one list endpoint whose authorisation is a single condition nobody wrote a test for
  • Websocket delivery, where a message renders optimistically for the sender and reaches nobody else, so two people leave a room each believing the other stopped replying
  • Reconnection, which is the genuinely hard part: a phone that slept through six messages has to know to ask for them, and a client that only listens will quietly miss half a conversation
  • Self-hosted course video, once you own it — transcoding, a bandwidth bill that scales with your members' enthusiasm, and media URLs that keep working long after someone's access ended
  • Push notifications, which arrive in triplicate, or at 4am in the wrong timezone, or not at all, and are the only reason anyone opens the thing twice a day
  • Paid tickets and installment plans, where a cancelled event is a batch of refunds and a payment schedule you personally now own
  • Automations that message members on your behalf, firing on a rule you wrote in March at whatever hour it happens to trigger in October
  • The archive: chat is the least portable data in software, and years of it in a schema only your app understands is not a migration path
and then, at 3am

Sunday evening, twenty minutes before a cohort call that has been in forty calendars for three weeks, the websocket process stops accepting connections and every channel goes quiet at once. Nobody emails you. They do what people in a dark room do — someone posts a Discord invite in the one tab still serving from cache, and by the time you have found the file-descriptor limit you never raised, thirty of them are in there talking. You bring the server back at eleven. The room is empty, and the messages you were so careful to persist are all still present, being read by no one. What you built was never the messages. It was the habit of opening the tab, and a habit relocates in a single evening.

Is that you?

the verdict is a default, not a law

ship it if
  • The group is free, small, and already knows you — a book club, a cohort of twelve, colleagues
  • Nobody pays for access, so nothing you break is a refund conversation
  • You would be equally happy running it in Discord and are doing this because building it is the fun part
  • Losing every message tomorrow would be a shrug rather than an announcement
don’t ship it if
  • Members pay for access, courses or tickets
  • There is a searchable member directory and no rate limit on the endpoint behind it
  • You are hosting course video yourself instead of pointing at a video host
  • You have ever gone twelve hours without checking your phone, because that is your outage window
  • The community is somebody's livelihood, including yours

If you build it anyway

the checklist, then the prompt that enforces it

  1. Treat the member directory as the crown jewels rather than as a page. Require a session, paginate with hard caps, rate-limit per account, and log who enumerated it — a roster of paying members is a lead list, and it leaves through one under-authorised endpoint.
  2. Persist messages before you deliver them, and make clients reconcile from a cursor on reconnect. Anything that exists only in a socket frame is a message somebody will swear they sent.
  3. Do not host video. Use a video host with short-lived signed URLs, and check that revoking access invalidates the URL and not merely the link in the UI.
  4. Let Stripe own subscription and ticket state, reconcile on a schedule rather than trusting webhook delivery, and do not implement installment schedules yourself.
  5. Any automation that messages members is a bulk sender. Give it a dry-run mode, a per-member daily cap and quiet hours before its first rule goes live.
  6. Build a global pause switch — notifications, automations, digests — that works from a shell without a deploy.
  7. Decide the uptime story before the feature list, and publish it. "Best effort, one person, European evenings" is a fine promise. Silence is not.
  8. Export in week one: channels as JSONL with stable ids and authors, uploads as files, members as CSV. It is the only thing that makes leaving your own software survivable.
the guardrail prompt
I am building a private community: real-time channels, DMs, a member directory,
courses and paid access. Treat the roster and message durability as the product
and the feed as decoration. Push back if I ask for these out of order.

1. Write the authorisation model in one place before any feature: who may read
   each object type, and how membership is decided. Every handler consults it,
   including directory, search and admin routes.
2. The directory is the highest-value object here, not the chat. Require a
   session, paginate with hard caps, rate-limit per account, log who listed it.
   Write the test that tries to page through it unauthenticated.
3. Messages persist before they fan out. Write to the database, then push over
   the socket, and have clients re-fetch from a cursor on reconnect. Show me the
   reconnect path before you show me the typing indicator.
4. Build export before import: channels as JSONL with stable ids and authors,
   uploads as files, members as CSV.
5. Then deletion. Enumerate in code every place member data lands — tables,
   object storage, email logs, search index, caches — and extend that list in
   the same commit as any new table.
6. Do not host or transcode video. Use a video host with short-lived signed
   URLs, and make revocation invalidate the URL rather than the link.
7. Stripe owns subscription and ticket state. Reconcile on a schedule, make
   handlers idempotent, and tell me what a failed payment does to access before
   writing it. No installment plans.
8. Anything that messages members automatically gets a dry-run mode, a
   per-member daily cap and quiet hours before its first rule ships.
9. Add a global pause switch for notifications, automations and digests that I
   can hit from a shell with no deploy.
10. Rate-limit signup, invite, message and upload from the first commit.
11. Out of scope on purpose: mobile apps, live video rooms, moderation tooling.
    Say plainly that live video is a hosting bill rather than a feature, and
    that Heartbeat's $49/month mostly buys somebody else being awake on Sunday.
paste this before you build — not after something breaks31 lines · 2091 chars

That one keeps you out of trouble. For the prompt that actually builds it, canivibecodeit.com has one.

their build prompt ↗

Or don’t build it

the boring option, and the way back out

just pay for it

The moment members pay, or the moment a directory of them exists. $49/month is under two dollars a head across thirty members and it buys a branded mobile app, a video host, a payments integration and an on-call rota that isn't you. Compare the separate payment processing fee — 5% falling to 1.25% with scale — against Stripe's, because that is the number that actually differs. If the group is free and asynchronous, self-host Zulip or Discourse and skip both.

$49/mo is cheaper than your weekend.

your exit plan, if you already built it

There are two exits and only one is technical. The technical one is easy if you start early and impossible if you don't: channels as JSONL with stable message ids, authors and timestamps, uploads as files, members as CSV, courses as markdown plus video files. The other is that chat archives are the least portable data in software — nothing imports them meaningfully and nobody re-reads them — so the real migration is announcing a new address and hoping people follow. Assume you end up on a hosted platform eventually, and keep the members list, the course content and the payment relationships in a shape you can pick up and carry.

prior art · someone already did this
Discourse

Mature open-source community discussion platform with strong moderation and search.

Zulip

Open-source threaded team chat with self-hosting and a real export format, which is the socket layer you were about to write.

Questions

You said much the same about Circle. What is different here?

Circle is asynchronous — posts, spaces, comments — and its sharpest edge is a private message leaking through an id in a URL. Heartbeat is real-time, which changes the shape of the failure entirely. Nothing leaks; the room simply goes quiet, everyone notices at the same second, and a community that can relocate itself in twenty minutes does. The second difference is the member directory, which Heartbeat sells as a feature and which is structurally an export button for your whole membership list.

What if I just use Discord and stop paying for anything?

Genuinely reasonable, and it is what your members will do on their own the first time you go down. What you give up is the part Heartbeat charges for: courses tied to membership, paid events, a directory people can search, and a space not owned by a company optimising for something else. What you gain is never being the reason a conversation stopped.

Are the courses easier than the chat?

The lesson structure is, right up until the video. Hosting your own means transcoding, storage, bandwidth that scales with enthusiasm, and access control on media URLs — which is exactly where homemade systems leak, because the lesson page checks membership and the mp4 does not. Point at a video host with short-lived signed URLs and the courses become an afternoon.

sources
  • GDPR Art. 5 — principles relating to processing of personal data (EU)
  • GDPR Art. 32 — security of processing (EU)
did you build it?

Every week, someone ships something they shouldn’t have.

New verdicts, the worst thing that landed in the trap, and the occasional incident report. No other email, ever.

also on the regret index
CircleYOUR FUNERAL

A forum is a weekend. A paid community is a company that five hundred strangers have already given their card to.

Mattermost ProfessionalYOUR FUNERAL

You can self-host the real thing this afternoon. Rebuilding it only makes you the one who gets paged.

Mighty NetworksYOUR FUNERAL

A community isn't a feature you ship. It's a duty of care with a subscription attached and a report button.

last reviewed 2026-08-04 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice