Skip to content

Repository files navigation

TalkNest

TalkNest is a full-stack real-time chat MVP built from the PRD. It includes an Expo React Native app, a Node.js Socket.io backend, SQLite persistence, JWT auth with signup, personal handles, attachment messages, timestamps generated on the server, a dark theme, and a Vite/Three.js landing page.

Apps

  • apps/server - Express, Socket.io, JWT auth, registration, SQLite via node:sqlite, Zod validation, attachment validation, and integration tests.
  • apps/mobile - Expo React Native signup/login and chat app with a sidebar inbox, persisted sessions, message history, direct chats by handle, attachment sending, dark theme, logout, and connection state.
  • apps/web - Vite React landing page with a responsive Three.js hero scene, product preview, app CTA, and dark theme toggle.

Requirements

  • Node.js >=22.5.0
  • npm

node:sqlite is currently experimental in Node, so the server may print an experimental warning during tests or startup.

Setup

npm install
cp apps/server/.env.example apps/server/.env

No demo users are seeded. Create an account in the app, then create a second account in another browser/session if you want to test personal chat locally.

Chat Features

  • Users get a unique handle and can open one-to-one chats by entering another user handle.
  • The main app uses a left rail, chat list, and active conversation layout inspired by modern messaging apps.
  • The app rail and chat list sidebar can be collapsed independently.
  • Home, Chat, Contacts, Notifications, Calendar, and Settings nav items open dedicated panels.
  • Settings supports dark theme plus editable display name, username, handle, and email.
  • Messages can include text, a photo, a video, or one document attachment.
  • Supported attachment types: JPEG, PNG, WebP, GIF, MP4, MOV, WebM, PDF, DOC, DOCX, PPT, PPTX, and TXT.
  • Size limits: photos and videos up to 4 MB; documents up to 2 MB.
  • Dark theme can be changed from Settings or toggled with Command+D on macOS and Ctrl+D elsewhere.

Run Locally

Start all runtimes:

npm run dev

Useful individual commands:

npm run dev:server
npm run dev:web
npm run dev:mobile

Default URLs:

  • Backend API: http://localhost:4000
  • Landing page: http://localhost:5173
  • Expo web/mobile dev server: shown by Expo in the terminal

The landing page links to the main app with VITE_TALKNEST_APP_URL. It defaults to http://127.0.0.1:8081 for local Expo web:

VITE_TALKNEST_APP_URL=http://127.0.0.1:8081 npm run dev:web

For a physical device, set the mobile app API URL to a LAN-reachable backend:

EXPO_PUBLIC_API_URL=http://YOUR_LAN_IP:4000 npm run dev:mobile

Verification

npm run typecheck
npm run test
npm run build
npm run verify

Visual validation for the Three.js landing page requires the web dev server:

npm run dev:web
npm run test:visual:web

The visual check saves screenshots in apps/web/artifacts/ and verifies that the Three.js canvas is not blank on desktop and mobile viewports.

Vercel Deployment

This repository is configured to deploy the Vite landing page to Vercel from the repo root.

npm run deploy:vercel

The Vercel build uses:

  • Build command: npm run build -w @talknest/web
  • Output directory: apps/web/dist
  • Config file: vercel.json

The real-time chat backend should be deployed separately to a long-running Node host because Socket.io WebSockets and SQLite persistence are not a good fit for Vercel serverless functions. After the backend is hosted, point the mobile app to it with EXPO_PUBLIC_API_URL.

API

  • GET /health - service health
  • POST /api/auth/register - creates a user and returns { token, user }
  • POST /api/auth/login - returns { token, user }
  • GET /api/auth/me - validates a bearer token
  • PATCH /api/auth/me - updates display name, username, handle, or email and returns a refreshed { token, user }
  • GET /api/users - returns public users and their handles
  • POST /api/direct-conversations/resolve - accepts { handle } and returns a private room for the authenticated user and that handle
  • GET /api/messages?roomId=lobby - returns recent room messages

Socket.io events:

  • Client emits room:join with { roomId } before opening a private room
  • Client emits message:send with { roomId, text, attachment? }
  • Server broadcasts message:new with message ID, sender, text, optional attachment, type, room, and timestamp
  • Server emits socket:ready after authenticated connection

The shared lobby uses roomId=lobby. Personal chat room IDs are generated by the backend after resolving a user handle. Only the two participants can load history, join the room, or send messages in that personal conversation.

About

Real-time chat app built with React Native, Node.js, and Socket.io.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages