← Projects

Bablworld

Social collections app with AI chat and personalised feeds, in four languages on iOS and Android.

bablworld.com landing page

Bablworld is a social app for collecting things from across the internet. A babl is a curated collection: Instagram posts, X threads, YouTube videos, TikToks, Pinterest pins and Spotify tracks gathered under one title, which other people can follow, comment on and share. It runs on iOS and Android in English, Turkish, French and Indonesian.

App and API

The app is React Native on Expo, with over-the-air updates through EAS and GitHub Actions. Behind it is a NestJS API on Prisma and PostgreSQL: collections, feeds, comments, follows, blocks, reports and notifications, plus importers that turn a link from each platform into structured content.

How a link becomes a babl A user shares a link from the app. The API runs the importer for that platform and stores the post as structured content inside a collection.

Parts: Mobile app (React Native · Expo), Website (Next.js · embeds), Bablworld API (NestJS · Prisma), Link importers (one per platform), Social platforms (posts · videos), Postgres (babls · comments).

  • Mobile app to Bablworld API (share link)
  • Website to Bablworld API
  • Bablworld API to Link importers
  • Link importers to Social platforms
  • Link importers to Postgres (structured)

Direct messages run over Socket.IO with unread counts, and push notifications go through OneSignal with deep links. Users buy coins through RevenueCat, confirmed by authenticated webhooks, and spend them on gifts. Sign-in is by phone number through Prelude, and media goes to Cloudflare R2 through presigned uploads.

AI and the feed

The in-app assistant searches the user’s collections and the social platforms through OpenAI function calling, and suggests babls inline in the chat. Collections are embedded with pgvector, which powers semantic search and AI-generated collections. The home feed averages the embeddings of the babls a user recently interacted with, weighted by the kind of interaction, and caches that vector in Redis, recomputing it in the background every 20 interactions. Postgres returns the nearest published babls, leaving out the user’s own, blocked accounts and anything viewed recently, and the service ranks that shortlist by similarity, recency and engagement. A user with no history gets the same shortlist ordered by score and recency instead.

How the home feed is ranked One embedding stands for what a user has engaged with. Postgres finds the nearest babls with pgvector, and the service re-ranks that shortlist by similarity, recency and engagement.
  1. Mobile app to Feed service: next page of the feed
  2. Feed service to Redis: cached user embedding?
  3. Feed service to Postgres: on a miss: recent interactions
  4. Feed service to Redis: cache the average
  5. Feed service to Postgres: nearest babls by vector distance
  6. Postgres to Feed service: shortlist, minus blocked and seen
  7. Feed service to Postgres: likes, shares, comments, views
  8. Feed service: score and sort
  9. Feed service to Mobile app: ranked page
  10. Mobile app to Feed service: interactions
  11. Feed service to Redis: recompute every 20 interactions

Around the app sit a Next.js website, which handles SEO, app deep links and embeddable babl pages, and an internal admin dashboard with AI content generation on a QStash job queue.