A multilingual mobile messaging app that automatically translates messages into your preferred language. Talk to anyone, anywhere!
π New to coding? Check out SETUP.md for a beginner-friendly step-by-step guide!
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β INTOK ARCHITECTURE β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ
β π± Mobile App β β π± Mobile App β β π Web App β
β (iOS/Android) β β (iOS/Android) β β (Browser) β
β User: Alice β β User: Carlos β β User: Yuki β
β Lang: English β β Lang: Spanish β β Lang: Japanese β
ββββββββββ¬ββββββββββ ββββββββββ¬ββββββββββ ββββββββββ¬ββββββββββ
β β β
β REST API (HTTP) β REST API (HTTP) β REST API (HTTP)
β + Socket.IO (WS) β + Socket.IO (WS) β + Socket.IO (WS)
β β β
ββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β π₯οΈ NODE.JS SERVER β
β (Express.js) β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β API ROUTES β β
β β /api/auth/* - Login, Register, Token Refresh β β
β β /api/users/* - Profile, Language Settings, Search β β
β β /api/conversations - List, Create Conversations β β
β β /api/messages/* - Message History, Translation Preview β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β SOCKET.IO HANDLERS β β
β β message:send β Receive message, detect language, translate, store β β
β β message:receive β Send translated message to recipient β β
β β message:typing β Typing indicators β β
β β message:read β Read receipts β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βββββββββββββββββββββ ββββββββββββ΄βββββββββββ βββββββββββββββββββββ β
β β π Auth Service β β π Translation Svc β β π¬ Message Serviceβ β
β β - JWT tokens β β - Language detect β β - Store messages β β
β β - Password hash β β - Translate text β β - Fetch history β β
β β - Session mgmt β β - Cache results β β - Real-time sync β β
β βββββββββββββββββββββ ββββββββββββ¬βββββββββββ βββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββββββ βββββββββββββββββββββββ βββββββββββββββββββ
β π PostgreSQL β β π€ AI Provider β β π΄ Redis β
β β β (configurable) β β β
β - Users β β β β - Translation β
β - Messages β β βββββββββββββββββ β β cache β
β - Conversationsβ β β OpenAI β β β - User sessionsβ
β - Translations β β β (gpt-4o-mini) β β β - Socket IDs β
β β β βββββββββββββββββ€ β β β
β β β β Claude β β β β
β β β β (haiku) β β β β
β β β βββββββββββββββββ€ β β β
β β β β DeepSeek β β β β
β β β β (chat) β β β β
β β β βββββββββββββββββ β β β
βββββββββββββββββββ βββββββββββββββββββββββ βββββββββββββββββββ
Alice (English) sends "Hello, how are you?" to Carlos (Spanish):
1. π± Alice's App
βββΊ Socket.IO: message:send { content: "Hello, how are you?", conversationId: "xxx" }
2. π₯οΈ Server receives message
βββΊ Detect language β "en" (English)
βββΊ Store original message in PostgreSQL
βββΊ For each recipient, translate to their language:
3. π€ AI Provider (for Carlos - Spanish)
βββΊ Input: "Hello, how are you?" (en β es)
βββΊ Output: "Β‘Hola! ΒΏCΓ³mo estΓ‘s?"
4. π΄ Redis
βββΊ Cache translation for future requests
5. π± Carlos's App
βββ Socket.IO: message:receive {
originalContent: "Hello, how are you?",
translatedContent: "Β‘Hola! ΒΏCΓ³mo estΓ‘s?",
originalLanguage: "en",
targetLanguage: "es"
}
6. π± Carlos sees: "Β‘Hola! ΒΏCΓ³mo estΓ‘s?"
βββΊ (Can tap to view original English)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β YOUR WINDOWS MACHINE β
β βββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββ β
β β π Web Browser β β π± Expo Go App β β
β β localhost:8081 β β (on your phone) β β
β β β β β β
β β React Native Web β β Connects via WiFi to: β β
β β (Expo Web) β β http://192.168.2.62:3001 β β
β ββββββββββββ¬βββββββββββ ββββββββββββ¬βββββββββββββββββββββββ β
β β β β
β β HTTP/WebSocket β HTTP/WebSocket β
β ββββββββββββββββββββββββββββΌββββββββββββββββββββββββββ€
β β β
β βββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββ β
β β WSL (Ubuntu) β β β
β β βββββββββββββββββββββββββββββββ β β β
β β β π Source Code β β β β
β β β /home/ayepez/github/ β β β β
β β β messaging-app/ β β β β
β β βββββββββββββββββββββββββββββββ β β β
β βββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββ
β
Network (LAN) β 192.168.2.x
β
ββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββ
β PROXMOX VM (Ubuntu) β IP: 192.168.2.62 β
β βββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββ β
β β π₯οΈ Node.js Server β β
β β Port 3001 β β
β β (PM2 managed) β β
β ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ β
β β β
β βββββββββββββββββββββββΌββββββββββββββββββββββ β
β βΌ βΌ βΌ β
β βββββββββββ βββββββββββββββ βββββββββββββ β
β βπ Postgresβ β π΄ Redis β β π€ Claude β β
β βPort 5432 β β Port 6379 β β API β β
β β(Docker) β β (Docker) β β (Internet)β β
β βββββββββββ βββββββββββββββ βββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
We are migrating from React Native (Expo) to fully native apps:
| Platform | Technology | Status |
|---|---|---|
| Android | Kotlin + Jetpack Compose | π§ In Development |
| iOS | Swift + SwiftUI | π§ In Development |
| React Native | Expo | β Production (being deprecated) |
dev β Development builds (simulators)
stage β Internal testing (Play Store Internal + TestFlight)
main β Production release (Play Store + App Store)
π See NATIVE_MIGRATION.md for detailed setup and deployment instructions.
After pushing to the dev branch, the CI/CD pipeline builds debug artifacts for both Android and iOS. Here's how to download and install them on your local simulators:
# Install GitHub CLI (if not already installed)
brew install gh
# Authenticate with GitHub
gh auth login# 1. Find the latest successful run
gh run list --branch dev --limit 5
# 2. Download artifacts (replace RUN_ID with the actual run ID)
gh run download RUN_ID -D ./builds
# 3. Install Android APK to emulator
# (Make sure Android emulator is running)
adb install ./builds/intok-android-debug-*/app-debug.apk
# 4. Install iOS app to simulator
# (Make sure iOS simulator is running)
xcrun simctl install booted ./builds/intok-ios-debug-*/Intok.app# Android (emulator must be running)
gh run download $(gh run list --branch dev --limit 1 --json databaseId -q '.[0].databaseId') -D ./builds && \
adb install ./builds/intok-android-debug-*/app-debug.apk
# iOS (simulator must be running)
gh run download $(gh run list --branch dev --limit 1 --json databaseId -q '.[0].databaseId') -D ./builds && \
xcrun simctl install booted ./builds/intok-ios-debug-*/Intok.app# Start Android emulator
emulator -avd Pixel_8_API_35 &
# Start iOS simulator
open -a Simulator
# Or specific device:
xcrun simctl boot "iPhone 15"- Real-time messaging with WebSocket support
- Automatic translation powered by Claude AI (Anthropic)
- Translation preview before sending (1-to-1 chats)
- Group chat support with per-user translation
- Voice messages (Phase 2)
- Message caching with Redis to minimize API calls
- 16 supported languages including English, Spanish, French, Chinese, Japanese, etc.
Option A: Traditional Server (server/)
- Node.js + TypeScript - Server runtime
- Express - REST API framework
- Socket.IO - Real-time WebSocket communication
- PostgreSQL + Prisma - Database
- Redis - Translation caching
Option B: Serverless (Recommended) (server-serverless/)
- AWS Lambda - Serverless functions
- API Gateway - HTTP + WebSocket APIs
- DynamoDB - Serverless database (pay-per-request)
- No Redis needed - Translations cached in DynamoDB
- OpenAI - GPT-4o-mini model (default, fast & affordable)
- Claude (Anthropic) - Claude Haiku model (~$0.25/million input tokens)
- DeepSeek - DeepSeek Chat (~$0.14/million tokens, FREE tier available)
Switch providers via AI_PROVIDER environment variable.
- React Native + Expo - Cross-platform mobile framework
- Expo Router - File-based navigation
- Socket.IO Client - Real-time communication
- Zustand - State management
- AsyncStorage - Token storage
messaging-app/
βββ server/ # Traditional Express server (local dev)
β βββ prisma/ # PostgreSQL schema
β βββ src/
β βββ routes/ # REST API endpoints
β βββ services/ # Translation service
β βββ socket/ # Socket.IO handlers
β
βββ server-serverless/ # AWS Lambda serverless (production)
β βββ template.yaml # AWS SAM CloudFormation
β βββ src/
β βββ handlers/ # Lambda functions
β βββ lib/
β βββ translation.ts # DeepSeek API + Ollama support
β
βββ mobile/ # React Native (Expo) app
β βββ app/ # Expo Router screens
β β βββ (auth)/ # Login & Register
β β βββ (app)/ # Conversations, Chat, Settings
β βββ src/
β β βββ services/ # API & WebSocket clients
β β βββ store/ # Zustand stores
β β βββ constants/ # Theme & languages
β βββ assets/ # App icons & images
β
βββ infrastructure/
β βββ aws/ # AWS deployment config
β β βββ samconfig.toml
β βββ ollama/ # Self-hosted AI setup
β βββ docker-compose.yml
β βββ setup.sh
β
βββ shared/ # Shared TypeScript types
βββ DEPLOYMENT.md # Detailed deployment guide
βββ README.md # This file
For Traditional Server:
- Node.js >= 18
- PostgreSQL database
- Redis server
- AI API key (OpenAI, Claude, or DeepSeek)
For Serverless (Recommended):
- Node.js >= 18
- AWS Account (free tier eligible)
- AWS CLI + SAM CLI installed
- AI API key (OpenAI, Claude, or DeepSeek)
cd messaging-app
# Install dependencies
npm install
# Create server/.env file
cat > server/.env << EOF
DATABASE_URL="postgresql://postgres:password@localhost:5432/lingualink"
REDIS_URL="redis://localhost:6379"
AI_PROVIDER="openai"
OPENAI_API_KEY="your-openai-api-key"
JWT_SECRET="your-super-secret-jwt-key"
JWT_REFRESH_SECRET="your-refresh-secret-key"
PORT=3001
CORS_ORIGIN="*"
EOF
# Generate Prisma client
npm run db:generate
# Run database migrations
npm run db:migrate
# Seed demo data (optional)
npm run db:seed
# Start the server
npm run dev:servercd mobile
# Install dependencies
npm install
# Create .env file for mobile
cat > .env << EOF
EXPO_PUBLIC_API_URL=http://YOUR_SERVER_IP:3001
EXPO_PUBLIC_WS_URL=http://YOUR_SERVER_IP:3001
EOF
# Start Expo development server
npm startThen scan the QR code with Expo Go app on your phone.
After seeding, you can use these accounts:
alice@example.com/password123(English)carlos@example.com/password123(Spanish)marie@example.com/password123(French)yuki@example.com/password123(Japanese)
- Apple Developer Account ($99/year) for iOS
- Google Play Developer Account ($25 one-time) for Android
- EAS CLI installed:
npm install -g eas-cli
cd mobile
# Login to Expo
eas login
# Configure your project
eas build:configure
# Build for iOS
eas build --platform ios --profile production
# Build for Android
eas build --platform android --profile production
# Submit to App Store
eas submit --platform ios
# Submit to Google Play
eas submit --platform android-
iOS (App Store Connect)
- Create app in App Store Connect
- Update
app.jsonwith your bundle identifier - Configure push notification certificates
-
Android (Google Play Console)
- Create app in Play Console
- Generate upload key and configure signing
- Set up Play App Signing
See Expo EAS Submit docs for detailed instructions.
POST /api/auth/register- Register new userPOST /api/auth/login- Login userPOST /api/auth/refresh- Refresh access token
GET /api/users/me- Get current userPATCH /api/users/me/language- Update preferred languageGET /api/users/search?q=query- Search users
GET /api/conversations- Get all conversationsPOST /api/conversations- Create conversationGET /api/conversations/:id/messages- Get messagesPOST /api/messages/preview-translation- Preview translation
message:send- Send a messagemessage:receive- Receive translated messagemessage:typing- Typing indicatormessage:read- Read receipt
| Service | Purpose | How to Get | Cost |
|---|---|---|---|
| OpenAI API | AI Translation (default) | https://platform.openai.com/api-keys | ~$0.15/M tokens |
| Claude API | AI Translation (alt) | https://console.anthropic.com/ | ~$0.25/M tokens |
| DeepSeek API | AI Translation (alt) | https://platform.deepseek.com/ | FREE tier |
| AWS Account | Serverless hosting | https://aws.amazon.com/free | Free tier available |
| Apple Developer | iOS App Store | https://developer.apple.com/programs/ | $99/year |
| Google Play Developer | Android Play Store | https://play.google.com/console | $25 one-time |
| Expo Account | Mobile builds | https://expo.dev/signup | FREE |
Create file: server/.env
# ============================================
# DATABASE (Required)
# ============================================
# PostgreSQL connection string
# Format: postgresql://USER:PASSWORD@HOST:PORT/DATABASE
DATABASE_URL="postgresql://postgres:your_password@localhost:5432/lingualink"
# ============================================
# REDIS (Required for caching)
# ============================================
# Redis connection string
# Local: redis://localhost:6379
# Cloud (Upstash free tier): redis://default:xxx@xxx.upstash.io:6379
REDIS_URL="redis://localhost:6379"
# ============================================
# AI TRANSLATION (Required - Choose one provider)
# ============================================
# Set which AI provider to use: "openai" | "anthropic" | "deepseek"
AI_PROVIDER="openai"
# OpenAI API Key (if AI_PROVIDER=openai)
# Get it at: https://platform.openai.com/api-keys
OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# Anthropic/Claude API Key (if AI_PROVIDER=anthropic)
# Get it at: https://console.anthropic.com/
ANTHROPIC_API_KEY="sk-ant-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# DeepSeek API Key (if AI_PROVIDER=deepseek)
# Get it at: https://platform.deepseek.com/api_keys (FREE tier!)
DEEPSEEK_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# ============================================
# AUTHENTICATION (Required)
# ============================================
# JWT secrets - generate random strings (32+ characters)
# Generate with: openssl rand -base64 32
JWT_SECRET="your-super-secret-jwt-key-min-32-chars"
JWT_REFRESH_SECRET="your-refresh-secret-key-min-32-chars"
# Token expiration (optional)
JWT_EXPIRES_IN="15m"
JWT_REFRESH_EXPIRES_IN="7d"
# ============================================
# SERVER CONFIG (Optional)
# ============================================
PORT=3001
NODE_ENV="development"
CORS_ORIGIN="*"These are set during sam deploy --guided:
# ============================================
# REQUIRED PARAMETERS
# ============================================
# JWT Secret for authentication
# Generate with: openssl rand -base64 32
JwtSecret=your-jwt-secret-min-32-characters
# Translation mode: "api" or "ollama"
TranslationMode=api
# ============================================
# IF TranslationMode=api (DeepSeek Cloud)
# ============================================
# Get free API key at: https://platform.deepseek.com/api_keys
DeepSeekApiKey=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# ============================================
# IF TranslationMode=ollama (Self-hosted AI)
# ============================================
# URL of your Ollama server
OllamaUrl=http://your-server-ip:11434Create file: mobile/.env
# ============================================
# API ENDPOINTS (Required)
# ============================================
# For LOCAL development:
EXPO_PUBLIC_API_URL=http://localhost:3001
EXPO_PUBLIC_WS_URL=ws://localhost:3001
# For AWS SERVERLESS (after deployment):
# Get these URLs from: sam deploy output or AWS Console
EXPO_PUBLIC_API_URL=https://xxxxxxxx.execute-api.us-east-1.amazonaws.com/prod
EXPO_PUBLIC_WS_URL=wss://xxxxxxxx.execute-api.us-east-1.amazonaws.com/prod
# For PRODUCTION with custom domain:
# EXPO_PUBLIC_API_URL=https://api.lingualink.app
# EXPO_PUBLIC_WS_URL=wss://ws.lingualink.appUpdate these in mobile/app.json:
{
"expo": {
"name": "LinguaLink",
"slug": "lingualink",
"ios": {
"bundleIdentifier": "com.yourcompany.lingualink" // Change this!
},
"android": {
"package": "com.yourcompany.lingualink" // Change this!
},
"extra": {
"eas": {
"projectId": "your-expo-project-id" // From expo.dev
}
}
}
}Update in mobile/eas.json for app store submission:
{
"submit": {
"production": {
"ios": {
"appleId": "your-apple-id@email.com",
"ascAppId": "1234567890" // From App Store Connect
},
"android": {
"serviceAccountKeyPath": "./google-service-account.json"
}
}
}
}# 1. Generate secure JWT secrets
openssl rand -base64 32 # Run twice, use for JWT_SECRET and JWT_REFRESH_SECRET
# 2. Get an AI API key (choose one):
# - OpenAI (default): https://platform.openai.com/api-keys
# - Claude: https://console.anthropic.com/
# - DeepSeek (FREE): https://platform.deepseek.com/
# 3. Create server/.env with all values above
# 4. Start the app
cd messaging-app
npm install
npm run db:generate
npm run db:migrate
npm run dev:server
# 5. In another terminal, start mobile
cd mobile
npm install
npm start- Never commit
.envfiles to git (already in.gitignore) - Rotate JWT secrets periodically in production
- Use AWS Secrets Manager for serverless production deployments
- Claude API - monitor usage at console.anthropic.com
- MVP: Text messaging + auto-translation
- Phase 2: Voice messages
- Phase 3: Group translation sync
- Phase 4: Message reactions & emojis
- Phase 5: Push notifications
- Phase 6: Offline mode with local cache
MIT