This repository contains both:
- Client: Expo + React Native app in the
Client/directory. - Server: Node.js (Express) API + Socket.IO realtime server in the
Server/directory.
The client talks to the server over HTTP (REST endpoints under /api) and subscribes to realtime updates via Socket.IO.
AfroLingo’s goal is to help learners reconnect with African languages and cultural context through:
- Bite-sized lessons and practice activities
- Progress + XP tracking
- Tutor discovery and 1:1 messaging (real-time)
- Community experiences (UI prototype demonstrating scalable feature structure)
This README is written to be useful in understanding how the project works.
- Client: React Native (Expo), Expo Router, TypeScript, Firebase (Auth), Socket.IO client
- Server: Node.js, Express, TypeScript, Socket.IO, Zod
- Database: PostgreSQL
- ORM: Prisma
- Realtime infra: Redis (presence, rate limiting, Socket.IO adapter)
- Lessons / units / stories / grammar tips / practice activities
- Progress tracking and XP/streak mechanics
- Onboarding flow and preference storage (theme + notification preferences)
- Tutor discovery served by the backend
- 1:1 chat with persisted threads/messages in Postgres (Prisma)
- Realtime delivery over Socket.IO with read/unread tracking
- A prototype-only Community tab implemented with mock data (no backend dependencies) demonstrating UI/UX and feature organization.
For the detailed Community summary, see Client/README_COMMUNITY.md.
- The app authenticates with Firebase Auth.
- HTTP requests go to the Express API (configured via
EXPO_PUBLIC_API_BASE_URL). - Socket.IO connections include a Firebase ID token in the handshake.
- The server verifies the token using Firebase Admin, then joins rooms (per-user and per-group).
- Durable data lives in Postgres (via Prisma).
- Redis provides presence, rate limiting, and Socket.IO scaling support.
- In-app notifications:
notification:new - Tutor chat:
tutor_chat:message:new - Groups: message + presence/typing patterns
Follow these steps to run the full project locally.
- Node.js 18+
- PostgreSQL (local or remote)
- Redis (recommended)
- A Firebase project for Auth
git clone https://github.com/vroymv/AfroLingo.git
cd AfroLingoClient
cd Client
cp .env.example .envSet at minimum:
EXPO_PUBLIC_API_BASE_URL(must include/api, e.g.http://localhost:3000/api)- the
EXPO_PUBLIC_FIREBASE_*variables
Server
cd ../Server
cp .env.example .envSet at minimum:
DATABASE_URLREDIS_URL(recommended)- Firebase Admin credentials (
GOOGLE_APPLICATION_CREDENTIALSORFIREBASE_PROJECT_ID+FIREBASE_CLIENT_EMAIL+FIREBASE_PRIVATE_KEY)
cd Server
npm install
npm run db:generate
npm run db:migrate
npm run db:seed
npm run devOpen a second terminal:
cd Client
npm install
npm startThen open iOS Simulator / Android Emulator / Web from the Expo CLI.
# Client/.env
EXPO_PUBLIC_API_BASE_URL=http://localhost:3000/api# Server/.env
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/afrolingo?schema=public
REDIS_URL=redis://localhost:6379The Socket.IO server expects a Firebase ID token sent during the handshake (client-side implementation details vary by screen):
// concept only
// io("http://localhost:3000", { auth: { token: "<firebase-id-token>" } })- Client docs:
Client/docs/ - Community summary:
Client/README_COMMUNITY.md - Server docs:
Server/DATABASE_GUIDE.md













