A full-stack Discord clone built with React, Convex, and Clerk.
- Frontend — React + TypeScript + Vite + Tailwind CSS
- Backend — Convex (real-time database, queries, mutations, file storage)
- Auth — Clerk (sign-in, sign-up, webhooks)
- Voice/Video — WebRTC with Convex as the signaling layer
- Real-time text chat with message edit/delete
- File and image attachments
- Typing indicators
- Voice and video channels (WebRTC P2P)
- Server and channel management
- Invite codes to join servers
- Online presence indicators
npm installCreate an app at dashboard.clerk.com and copy your publishable key.
npx convex devThis creates a project at dashboard.convex.dev, generates backend types, and starts the dev server.
Copy .env.example to .env.local and fill in your keys:
VITE_CONVEX_URL=https://your-project.convex.cloud
VITE_CLERK_PUBLISHABLE_KEY=pk_test_...npm run dev:frontendOr run both backend and frontend together:
npm run devIn your Clerk dashboard → Webhooks, add an endpoint:
https://your-project.convex.site/clerk-webhook
Subscribe to user.created and user.updated events. This keeps user records in sync between Clerk and Convex.
- Go to the Discord Developer Portal and create an application.
- Under "Bot" > "Privileged Gateway Intents", enable the required intents.
- Under "OAuth2" > "URL Generator", add the
applications.commandsandbotscopes. - Under "General Information", copy your Public Key.
Add the following to your .env.local:
DISCORD_PUBLIC_KEY=your-discord-public-key-here
Use Discord's API or a tool to register a command, e.g.:
curl -X POST "https://discord.com/api/v10/applications/<app_id>/commands" \
-H "Authorization: Bot <bot_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "echo",
"description": "Echo back your input",
"options": [{
"name": "text",
"description": "Text to echo",
"type": 3,
"required": false
}]
}'
In the Discord Developer Portal, set your Interactions Endpoint URL to:
https://<your-convex-deployment>.convex.site/discord-interactions
Type /echo hello in your Discord server. The bot should reply with hello.
Backend:
npm run convex:deployFrontend: Connect your GitHub repo to Vercel. Set VITE_CONVEX_URL and VITE_CLERK_PUBLISHABLE_KEY in the Vercel environment settings.