Skip to main content
Live on App Store
App Store ↗

Rhema Bible

Creator, mobile and serverless|React Native / serverless functions / Postgres

TLDR

Bible study app on Expo React Native with a .NET 8 serverless functions backend, Postgres, blob TTS, LLM provider streaming, and IAP provider. Shipped to the App Store with OTA updates. Product site: rhemabible.app.

Context. Readers need fast content access, notes, audio, and paid AI features on mobile, with a backend that can take App Store traffic and subscription webhooks without a fixed always-on API box.

ReactReact NativeExpo.NET 8serverless functionsPostgresEF Coremessage busobject storageLLM providerIAP provider

Architecture

System diagram

Rhema Bible architecture diagram

Component map

As deployed

Clients

RhemaApp

Expo / React Native

Admin suite

Next.js / admin identity provider

Marketing site

Vite SPA

Backend

serverless functions

.NET 8 isolated worker

message bus

email and activity queues

object storage

TTS cache, SAS delivery

Data and AI

PostgreSQL

EF Core / Neon

LLM provider

Chat and streaming

IAP provider

IAP webhook

What shipped

  • Clean Architecture on serverless: Domain, Application, Infrastructure, Api.Functions
  • App users on first-party JWT; admin operators on admin identity provider with an admin role
  • LLM provider streaming over SSE, freemium quota, and prompt-hash response caching
  • TTS via TTS provider into content-addressed object storage, returned as SAS URLs. Repeat requests are served from object storage to avoid paying the TTS provider again.
  • Message bus queues for email and activity writes with idempotent consumers
  • Product analytics and feature flags for mobile and backend release control

Backend

  • HTTP Functions under /api/v1 for auth, user, AI, notes, saved verses, TTS, and admin
  • Application services for auth, AI quota, notes, account deletion, and admin work
  • Postgres via EF Core for users, notes, bookmarks, OTP, and webhook or queue dedupe
  • IMemoryCache for profiles, repeated AI queries, prompts, and TTS existence checks
  • IAP provider webhook updates premium state and queues lifecycle email
  • TTS synthesize checks object storage first. Misses call the TTS provider, upload the MP3, then return a SAS URL

Request and event flow

  1. 01Client calls JWT-protected AI or TTS endpoints on serverless functions
  2. 02TTS checks object storage by content hash. Cache hit returns a SAS URL with no TTS provider call
  3. 03Cache miss synthesizes with the TTS provider, uploads the MP3 to object storage, then returns a SAS URL
  4. 04Email and recent-activity side effects publish to the message bus
  5. 05Notification Function sends mail; ProcessActivity writes to Postgres
  6. 06Timer Function warms popular Bible TTS audio into object storage
  7. 07IAP provider webhook updates subscription and queues lifecycle email

API domains

  • Auth and OTP
  • User profile and soft-delete
  • AI query, prayer, chat, stream
  • Notes and saved verses
  • TTS synthesize and warmup
  • Admin dashboard
  • IAP provider webhook

Key decisions

  • Expo Router, TanStack Query, and local SQLite for notes and bookmarks so core reading features work with intermittent connectivity.
  • Synthesize each TTS clip once with the TTS provider, store it in object storage under a content hash, then serve SAS URLs. Repeat plays hit object storage, not the TTS provider.
  • Warm popular verse audio on a timer to reduce first-play latency without synthesizing on every request.
  • Cache identical LLM provider prompts by hash for 24 hours. Cache hits skip the model call and do not consume freemium quota.
  • Re-read subscription state from Postgres before AI quota checks so an IAP provider purchase is not blocked by a stale memory cache.
  • Use first-party JWT for app users and admin identity provider only for the admin suite.

Availability

Open to opportunities

Open to senior product engineer roles with real ownership across the stack. Security-minded by default.

UK-based · Remote / hybrid · Permanent or contract