A full-stack realtime chat application built with Next.js App Router, Clerk authentication, and Convex for backend state + realtime sync.
- Clerk-based authentication (sign in / sign up)
- Protected
/chatroute via middleware - Direct and group conversations
- Realtime message sync (Convex reactive queries)
- Typing indicators
- Online/offline presence
- Unread count tracking with read sync
- Soft-delete for own messages
- Emoji reactions on messages
- Mobile-friendly chat layout
- Next.js 16 (App Router)
- React 19
- TypeScript
- Tailwind CSS
- Clerk (
@clerk/nextjs) - Convex (
convex,convex/react-clerk)
app/ # Routes and app shell
components/ # UI and feature components
chat/ # Chat shell, thread, auth sync
sidebar/ # Conversation list and discovery
ui/ # Shared UI primitives
convex/ # Backend schema, queries, mutations
hooks/ # Reusable client hooks (presence, unread, typing, scroll)
lib/ # Utilities
middleware.ts # Clerk route protectionThis project needs environment variables in two places:
- Frontend (
.env.local) - Convex deployment environment (via
npx convex env set)
Create .env.local in the project root:
NEXT_PUBLIC_CONVEX_URL=https://<your-convex-deployment>.convex.cloud
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...convex/auth.config.ts requires:
CLERK_JWT_ISSUER_DOMAIN=https://<your-clerk-domain>Set it with:
npx convex env set CLERK_JWT_ISSUER_DOMAIN https://<your-clerk-domain>For production:
npx convex env set --prod CLERK_JWT_ISSUER_DOMAIN https://<your-clerk-domain>Install dependencies:
npm installStart Convex dev deployment (in one terminal):
npx convex devStart Next.js app (in another terminal):
npm run devOpen:
http://localhost:3000for landing pagehttp://localhost:3000/chatfor chat (requires login)
npm run dev- Start Next.js dev servernpm run build- Build production bundlenpm run start- Start production servernpm run lint- Run lint checksnpm run typecheck- Run TypeScript checks
- Configure sign-in/sign-up in Clerk dashboard.
- Ensure your Clerk JWT template is configured for Convex (
applicationID: "convex"inconvex/auth.config.ts). - Add local and production domains in Clerk allowed origins/redirects.
npx convex deploySet required production backend env:
npx convex env set --prod CLERK_JWT_ISSUER_DOMAIN https://<your-clerk-domain>Set these production env vars in your hosting platform:
NEXT_PUBLIC_CONVEX_URLNEXT_PUBLIC_CLERK_PUBLISHABLE_KEYCLERK_SECRET_KEY
Then deploy your app.
- Sign in successfully
- Open
/chat - Send messages and reactions
- Confirm unread counts and presence updates
- Watch Convex logs if needed:
npx convex logs --prod-
Missing NEXT_PUBLIC_CONVEX_URL- Add
NEXT_PUBLIC_CONVEX_URLto.env.localand restart dev server.
- Add
-
Missing CLERK_JWT_ISSUER_DOMAIN- Set Convex env var:
npx convex env set CLERK_JWT_ISSUER_DOMAIN ...(dev)npx convex env set --prod CLERK_JWT_ISSUER_DOMAIN ...(prod)
- Set Convex env var:
-
error: src refspec main does not match any- Make sure you have an initial commit and correct branch name before pushing.
This project is for educational/demo use. Add a license file if you plan to distribute it publicly.