shouldivibecodeit

Should I vibe codePumble?

Run straightforward team channels, direct messages, threads, and file sharing

Your delete button sets a flag. The message is still in the search index, the backup and last night's push.

?

Their verdict, the Pro 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

Chat looks like the simplest CRUD app you will ever write, and for about a week it is. What you are actually building is an archive of everything your colleagues say when they believe they are speaking privately, and archives have obligations. Two of them will find you. The first is retention: your messages table has no policy, which means it keeps the salary conversation, the HR complaint and the API key someone pasted into a DM in 2027, forever, in whatever backups you were taking. The second is deletion, and it is worse than it sounds — a delete button that sets deleted_at leaves the text in the search index, the websocket replay buffer, the notification email that already went out and last night's snapshot, so the honest answer to "please remove that" is a shrug. It is telling that Pumble itself only exports public channels and reserves retention controls for its top tier: the vendor with a compliance team finds this hard. Your weekend version will have neither, and everybody's day stops when it goes down.

What actually breaks

not "if". the specific failures.

  • Deletion, because removing a message means removing it from the table, the full-text index, the unread cache, the mobile push that already fired and every backup — and only the first of those is one line
  • Retention, which does not exist unless you built it, so a DM thread from three years ago is still sitting there the day somebody's laptop is stolen
  • Offboarding, when a person leaves and nobody can answer whether their DMs are deleted, retained, or readable by the next admin
  • Export, which is the feature everyone assumes exists and nobody builds — note that the paid product only exports public channels, not DMs or private ones
  • Private channel membership, where a bug that adds someone to a channel is not a permission error, it is a person reading a conversation about themselves
  • Unread state, which sounds trivial and is the single fiddliest thing in the product: per-user, per-channel, per-device, and wrong forever if you get the ordering wrong
  • Push notifications, which need APNs and FCM credentials, a delivery worker, and the discipline not to put message content in the payload
  • Search, which is fine on ten thousand messages and needs a real index at a million, and which must respect channel membership on every query
  • Uptime, since the day your team's communication lives here is the day a Saturday deploy is everyone's problem and there is no other channel to tell them about it
  • File uploads, which are the same guessable-URL problem as everywhere else, except the files are screenshots of things people did not want shared
and then, at 3am

The message arrives on a Sunday: a contractor whose engagement ended in March has asked, politely and in writing, for their personal data to be deleted. You had not thought about them since March. You open the admin panel you built and discover it has an archive button and nothing else, so you write the query by hand. The messages go. Then you remember the search index, which is a separate service with its own copy, and after that the daily snapshots in object storage, thirty of them, each containing the full table. Around midnight you find the part you had genuinely forgotten: the notification worker writes the message body into an email digest, and those digests are in a transactional mail provider's log with a ninety-day retention you do not control. By two you have a spreadsheet of places the same paragraph exists and no confidence the list is complete, which is the actual answer to why deletion is a feature rather than a query.

Is that you?

the verdict is a default, not a law

ship it if
  • It is a hobby server for people who know it is a hobby server and use something else for anything that matters
  • Messages expire automatically after a short window, by design, and nobody expects history
  • There are no DMs and no private channels — everything in it is visible to everyone in it
  • The team is small enough that "it's down, use SMS" is a sentence you can actually say to all of them
don’t ship it if
  • It is the place your team is expected to be reachable during working hours
  • There are direct messages, because you have just become the custodian of everyone's private conversations
  • You cannot answer, today, what happens to a person's messages when they leave
  • There is no export, or the export does not include the private content people will ask for

If you build it anyway

the checklist, then the prompt that enforces it

  1. Write the retention policy before the first message is stored. A default of forever is a decision, not an absence of one, and it is the one you will regret.
  2. Build deletion as a job across every store, not a flag on a row: primary table, search index, caches, attachments and backups. Write down the list of places a message body exists and keep it in the repo.
  3. Never put message content in a push notification payload or an email digest. Send a pointer, not the text, and you remove two copies you cannot delete later.
  4. Export comes before search, and it must include DMs and private channels. The commercial product's export skips those and that is precisely the gap people discover at the worst moment.
  5. Enforce channel membership in the query for messages, search results, file downloads and link previews. A search index that does not filter by membership is a private channel with extra steps.
  6. Make offboarding a real feature: what happens to a departing user's DMs, who can read them afterwards, and how it is recorded. Decide once, in writing, rather than per-incident.
  7. Serve uploaded files through an authorised handler with short-lived URLs. Screenshots pasted into a private channel are the most sensitive thing in the whole database.
  8. Assume you will be down and plan for it: a status page somewhere else, and a documented fallback channel your team already knows about, because you cannot announce an outage inside the outage.
the guardrail prompt
I am building a team chat app: channels, direct messages, threads and file sharing. The failures I care about are being unable to actually delete a message and keeping everyone's private conversations forever by accident. Order the work so those come first.

1. Before any feature, write down every place a message body will exist: primary table, search
   index, caches, websocket replay buffer, push payloads, email digests, file attachments,
   backups. Keep that list in the repo and update it whenever you add a store.
2. Build hard deletion second, as a job that clears every entry on that list and reports what it
   touched. A deleted_at flag is not deletion and you should say so if I ask for one.
3. Choose a retention policy now — per workspace, per channel type, with a shorter default for
   DMs — and implement expiry before implementing history. Forever is a choice with
   consequences.
4. Never put message text in a push notification or an email digest. Send an identifier the
   client resolves after authenticating. That removes two copies you cannot later delete.
5. Build export before search, and include DMs and private channels. If you cannot include
   them, tell me which content is unrecoverable before I rely on it.
6. Channel membership is enforced in the query, for messages, search, file downloads and link
   unfurls. Write the test that searches as a non-member and asserts zero results.
7. Attachments are served through an authorised handler with short-lived URLs. No public bucket
   paths, including for thumbnails and previews.
8. Implement offboarding explicitly: what happens to a departing user's DMs, who can read them,
   what is logged. Ask me to decide rather than defaulting.
9. Message ids are opaque and unguessable, and there is no endpoint that returns a message by
   id without a membership check.
10. Treat unread state as a real design problem — per user, per channel, per device — and write
    the tests before the UI. It is the thing homemade chat always gets wrong.
11. Out of scope unless I ask again: guest accounts, external federation, message editing
    history, voice and video calls, and any kind of compliance export API.
12. Finish by telling me Pumble's free tier is unlimited users with unlimited history, Pro is
    three dollars a seat, and that neither of us wants to be the custodian of my colleagues'
    direct messages.
paste this before you build — not after something breaks29 lines · 2397 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

Almost immediately, and the numbers make this an unusually easy call. Pumble's free tier is unlimited users with unlimited message history, and Pro is three dollars a seat a month — for a team of eight that is under twenty-five dollars, against which you are weighing push infrastructure, an export that includes DMs, a deletion path across five data stores, and being personally on call for the channel your colleagues use to say they cannot work. Build a chat app to learn how presence and unread state work. Do not build the one your team depends on.

$2.99/mo is cheaper than your weekend.

your exit plan, if you already built it

Get the export working early and include the private content, because a chat archive without DMs is not an archive of the conversation that mattered. Dump messages, channels, memberships, threads and attachments to a documented JSON structure on a schedule, keep it somewhere your app cannot reach, and test a restore at least once. Mattermost and Zulip both have importers, so shaping the export towards one of their formats gives you a real destination rather than a folder of files. And plan the announcement, not just the migration: the last thing to switch off is the channel you would use to tell people you are switching things off.

prior art · someone already did this
Zulip

Mature open-source team chat with a threading model, retention settings and a full export already built.

Mattermost

Actively developed open-source Slack alternative, self-hostable, with compliance export and data retention as first-class features.

Questions

Why is chat harsher than a project tracker with the same number of users?

Because of what people put in it. A tracker holds tasks somebody wrote knowing colleagues would read them; chat holds the message people sent believing it was private, plus the credential someone pasted in a hurry, plus the complaint about a manager. The data is more sensitive, it is never reviewed, and the volume means nobody can audit it after the fact. That combination is why retention and deletion are the whole entry.

Pumble's free tier is unlimited. Is there any case for building this?

As a learning project, yes — real-time presence, unread state and message ordering are genuinely interesting problems and you will understand every chat app you use afterwards. As the thing your team relies on, no. The free tier removes the only argument that usually survives, which is cost, and leaves you weighing a weekend against being personally responsible for whether your colleagues can reach each other.

Is deletion really that hard?

It is hard in a boring way that catches everyone. The message body gets copied into a search index, a cache, a push notification, possibly an email digest, and every backup you took. Deleting the row deletes one of those. If you have not written down where the copies live, you cannot honestly answer a deletion request, and "we removed it from the app" is a different sentence from "it is gone". Write the list before you write the feature.

sources
  • GDPR Art. 5 — principles relating to processing of personal data
  • GDPR Art. 32 — security of processing
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
Mattermost ProfessionalYOUR FUNERAL

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

CircleYOUR FUNERAL

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

HeartbeatYOUR FUNERAL

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

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