A MERN-stack chat app built from scratch on the Google Gemini API (gemini-2.5-flash). In-app branding: PromptX. Threads are private per Google account.
- Frontend — React 19, Vite 7, React Context for state,
react-markdown+rehype-highlightfor rendering replies,@react-oauth/googlefor Google Identity Services. - Backend — Node.js, Express 5, Mongoose (MongoDB), Gemini
gemini-2.5-flashviafetch. Auth via Google ID-token verification (google-auth-library) + HS256 session JWT (jsonwebtoken).
PromptX/
├── Frontend/ # React + Vite SPA (see Frontend/README.md)
└── Backend/ # Express API + MongoDB (see Backend/README.md)
The two packages are independent — each has its own package.json and is installed and run separately. There is no npm workspace.
- Node.js (tested with v18+)
- A MongoDB instance (local or Atlas) and its connection string
- A Google Gemini API key (https://aistudio.google.com/apikey)
- A Google OAuth 2.0 Web client ID — create one at https://console.cloud.google.com → APIs & Services → Credentials → Create OAuth client ID → Web application. Add
http://localhost:5173(frontend) to Authorized JavaScript origins. You only need the client ID; the client secret is not used by this app.
# 1. Install dependencies for each package
cd Frontend && npm install
cd ../Backend && npm install
# 2. Backend env (required)
cp Backend/.env.example Backend/.env
# Fill in:
# MONGODB_URI — Mongo connection string
# GEMINI_API_KEY — from Google AI Studio
# GOOGLE_CLIENT_ID — the OAuth Web client ID
# JWT_SECRET — random hex string; generate with: openssl rand -hex 32
# Server fails fast on startup if any of these is missing.
# 3. Frontend env
cp Frontend/.env.example Frontend/.env
# Set:
# VITE_GOOGLE_CLIENT_ID — same Web client ID as the backend
# VITE_API_URL — optional, defaults to http://localhost:8080
# 4. One-time: if you ran a previous (pre-auth) version, drop the legacy
# threads collection. The new schema requires userId, so old rows fail
# Mongoose validation.
# mongosh "$MONGODB_URI"
# > db.threads.drop()Open two terminals:
# Terminal 1 — backend on http://localhost:8080
cd Backend && npx nodemon server.js
# Terminal 2 — frontend on http://localhost:5173
cd Frontend && npm run devThen open http://localhost:5173 in a browser, click Sign in in the nav, complete the Google flow, and you'll land in the chat app.
The frontend reads the backend URL from
VITE_API_URL(set inFrontend/.env, falls back tohttp://localhost:8080). If you change the backend port, update that env var — no code edits needed.
- Google sign-in via Google Identity Services; per-user thread scoping (each Google account has its own sidebar)
- Multi-thread chat history persisted in MongoDB
- New chat / switch thread / delete thread from the sidebar
- Markdown rendering with styled code blocks (
rehype-highlightclasses are emitted; no syntax-color theme bundled yet — code blocks render with the warp surface styling only) - Word-by-word typewriter animation for the latest assistant reply
- Warp-inspired terminal UI on
/app(window chrome, command palette, agent/cmd composer mode), a marketing landing page at/, and a dedicated sign-in page at/signin - Keyboard shortcuts: ⌘K new chat, ⌘P agent palette, Shift+↩ newline in composer
- Route guard:
/appis locked behind a valid session; logged-out visitors are redirected to/signin, and signing in there sends them on to/app
See LICENSE.