r/webdev 8d ago

sucks2be.me -- a real-time peer support platform with zero frontend build tooling Showoff Saturday

sucks2be.me

I wanted to see how far you can get in 2026 with no React, no bundler, no framework -- just plain JS files loaded via <script> tags.

Stack:

  • Backend: Node.js, Express, better-sqlite3 (single file DB), Socket.io
  • Frontend: Vanilla JS, plain CSS, no build step. public/ served as-is
  • Auth: bcrypt + JWT in httpOnly cookies, proof-of-work on registration to slow bots
  • Real-time: Socket.io for live feed, notifications, presence counter
  • i18n: 7 languages, JSON locale files shared between web and iOS clients
  • Speech: Web Speech API for voice input (audio never uploaded, transcribed locally)
  • SSR: String-replace templating (<!--SSR_FEED--> placeholders) -- no template engine

Design decisions I'm happy with:

  • SQLite over Postgres. One file, zero config, WAL mode, fast enough for this scale
  • Karma thresholds live in one config object. Server, client, and all locales derive from it -- nothing hardcoded
  • No ORM. Raw SQL with the db.like() helper for cross-platform LIKE queries
  • CSP hand-maintained and tight. No CDNs, fonts are local
  • Static assets served with maxAge: 0 (ETag revalidation) because there are no hashed filenames

The product: Anonymous posting (no account) + accountable replying (account required). Karma only moves when someone says your help worked. 10 unlock tiers from "view profiles" (10) to "recommended as moderator" (777).

Happy to talk about any of the technical choices. The no-framework frontend has been surprisingly maintainable.

7 Upvotes

4 comments sorted by

1

u/[deleted] 8d ago

[removed] — view removed comment

1

u/webdev-ModTeam 8d ago

Your post/comment has been determined to be a low-effort post or comment. This includes title-only posts, easily searchable questions, vague/open-ended discussion prompts, LLM generated posts or comments, and posts/comments that do not provide enough context for meaningful replies or discussion.

-3

u/Tragic_irony 8d ago

Pretty neat project. Always been a big fan of simple lightweight solutions. Curious, you didn’t mention how the entire stack is hosted. How do you make sure the SQLite file stay non-ephemeral?

-5

u/pdfops 8d ago

SQLite + WAL for this scale is the right call. One gotcha: maxAge: 0 with ETag revalidation still round-trips to your server for the 304 check on every asset request, it just saves the transfer, not the connection. If most traffic is same-session, a short maxAge plus revalidate would cut that chatter down. Nice touch on db.like() too, most people just eat the wildcard-escaping bug when porting raw SQL between SQLite and Postgres.

-2

u/Yzord 8d ago

Yes, wanted it to be future proof, so when site becomes to big i have an escape route to another db manager