Selected work
Full-stack App · Multi-platformTypeScript · Express · React 19 · MySQL · WebRTC · Docker · Electron

LoverChat

A realtime private messenger with end-to-end infrastructure across web, iOS, Electron desktop, HTTP API, and containerized backend with canary deployments.

A multi-platform instant messenger built on TypeScript with zero surveillance: end-to-end infrastructure across web, iOS (Capacitor), Electron desktop, and an HTTP API. Core server runs in a containerized backend with live WebSocket signaling, WebRTC voice/video calls, file attachments, and a release pipeline featuring sandboxed schema migrations and zero-downtime canary deployments.

Role — Solo developer
  • TypeScript
  • Express
  • React 19
  • Vite
  • MySQL 8.4
  • WebRTC
  • WebSocket (ws)
  • Electron
  • Capacitor
  • Tailwind CSS
  • Docker & Docker Compose
  • PHP (admin + API + dispatcher)

LoverChat is a realtime chat application architected for privacy and simplicity. Authentication is phone-only via OTP (voip.ms or Twilio), eliminating email/password baggage. The core backend runs as a single Express + ws process handling messaging, call signaling, and WebRTC peer setup; a MySQL database (shared between the chat backend on a VPS and admin dashboards on DreamHost) materializes conversations, read receipts, and contact invitations. Sessions are token-based and refreshed on each connection; the architecture deliberately avoids an identity provider to reduce complexity.

The frontend is React 19 with Vite, built as a dual-entry system so the unauthed onboarding and authed chat surfaces are physically separate bundles — the unauthed build cannot import post-auth code or API secrets. A PHP gate (in admin's index.php) reads a session cookie and serves the right HTML. Platforms include a web SPA + marketing site (DreamHost), an Electron desktop shell wrapping the web bundle (with installer auto-updates), and iOS via Capacitor + TestFlight. WebRTC calls use STUN and optional TURN, with fallback diagnostics; screen sharing swaps tracks in-place without renegotiation. File uploads go through a multipart form handler on the server, stored on disk, served via content-hashed URLs.

Deployment is a multi-surface canary system: the CI (GitHub Actions) builds each surface independently (marketing, admin, web client, HTTP API, database schema, dispatcher, chat backend), stages to DreamHost, and records manifest entries. A human clicks 'Promote' in the admin Releases page to go live, or auto-promote chains can advance surfaces when their dependencies are ready. Destructive schema changes are sandboxed first — cloned tables in loverchat_sandbox with sha8 suffixes. The dispatcher (single PHP file at the doc root) routes requests by reading live_state + canary tables to pick the right build tree. Rollback is atomic: snapshot before schema, restore after.

What's notable
  • Dual-entry React build: separate unauthed (onboarding) and authed (chat) bundles so the public entrypoint cannot import secrets or post-auth routes.
  • WebRTC 1:1 audio/video calls with screen sharing via track replacement, STUN/TURN negotiation, and diagnostic logging keyed to localStorage flags.
  • Multi-platform release: web (Vite SPA), iOS (Capacitor + TestFlight with automated ASC API syncing), Electron (electron-builder with auto-updates), and HTTP API (PHP on DreamHost).
  • Canary deployments with sandboxed schema: destructive migrations cloned to loverchat_sandbox; snapshot → schema → swap → rollback atomic; auto-rollback to last-known-good after error spike.
  • Phone-only auth (OTP via voip.ms primary + Twilio fallback); unified identity model (users.role + users.permissions) shared between chat backend and admin dashboard; no password, email, or external IdP.