Skip to content
FLOWleplusbeauPublic

About

Real-time Discord-style text chat — a Convex + Better Auth + TanStack Start showcase

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

💬 Echo

A real-time, text-only chat app with a Discord-style UI — built to show off Convex.

Servers, categorized channels, DMs, reactions, presence, typing indicators and file uploads — every message, reaction and status updates live on every screen, with no refresh and no websocket plumbing.

Features · Screenshots · How it works · Run it · Tech


Note: Echo is a personal learning project — a UI-style homage to Discord built to explore Convex + Better Auth. It is not affiliated with Discord and ships none of Discord's logos, brand assets, or code.

✨ What it shows off

Real-time chat is the perfect stress test for a reactive backend — and Convex makes it almost free. Every list below is a plain reactive query; updates fan out to all clients automatically.

Feature Convex primitive
🔄 Live messages Reactive useQuery (paginated) — new messages appear instantly for everyone in the channel/DM.
⌨️ Typing indicators A short-lived typing table; clients see "X is typing…" live and it self-expires.
🟢 Presence A heartbeat mutation updates lastSeen; the member list shows online / idle / dnd / offline in real time.
😀 Reactions A reactions table + toggle mutation; counts update live across clients.
📎 File / image attachments Convex file storage (generateUploadUrl + ctx.storage).
💬 Direct messages 1:1 conversations alongside servers, find-or-create by a sorted-id key.
🧹 Scheduled cleanup A cron prunes stale typing/presence rows every 30 minutes.
🔐 Auth Better Auth running inside Convex (email + password), wired for SSR with TanStack Start.

📸 Screenshots

Direct messages — friends list & conversations

DM home A conversation (with profile panel)
DM home DM conversation

A server — categorized channels, role-colored member list

Server channel

Real-time in action

A message sent by another client appears instantly, and you can see who's typing — no refresh.

Realtime: live message + typing indicator

Sign in

Login

🎮 How it works

  1. Sign in (Better Auth, email + password). A lightweight profile is created on first login.
  2. Create or join a server with a short invite code. Each server has categories of text channels.
  3. Chat in a channel: messages, emoji reactions, "is typing…", and image/file uploads — all live.
  4. DM anyone: open a 1:1 conversation from the Direct Messages list.
  5. The member list shows everyone grouped by role, with live presence dots.

🧱 Tech stack

🚀 Run it locally

Requires Bun and the Convex CLI.

bun install

# 1. Start Convex — creates a local (or cloud) deployment and writes the URLs to .env.local
convex dev

# 2. Set the auth env vars on the deployment (in another terminal)
convex env set BETTER_AUTH_SECRET "$(openssl rand -base64 32)"
convex env set SITE_URL "http://localhost:3000"

# 3. Add VITE_SITE_URL=http://localhost:3000 to .env.local, then run the frontend
bun run dev   # http://localhost:3000

Open http://localhost:3000, create an account, and start a server. Want it to look populated? Seed a demo server (cast of channels, members, messages, reactions and a couple of DMs):

convex run seed:seed '{}'   # attaches the demo server to your signed-in account

💡 The seeded "members" are display-only profiles (no real accounts). To see live cross-client updates with real identities, open the app in two browsers and sign in as two users.

🗂️ Project layout

convex/
  schema.ts        # profiles, servers, members, categories, channels, dms, messages, reactions, presence, typing
  auth.ts          # Better Auth component + createAuth
  auth.config.ts   # Convex auth provider for Better Auth
  http.ts          # Better Auth HTTP routes
  convex.config.ts # registers the betterAuth component
  users.ts         # getMe / ensureProfile / updateProfile / searchUsers
  servers.ts       # create/join servers, channels, member list (with presence)
  messages.ts      # paginated list, send, edit, delete, uploads
  reactions.ts     # toggle emoji reactions
  dms.ts           # open/list direct messages
  presence.ts      # heartbeat, typing, listTyping
  crons.ts         # periodic cleanup of stale typing/presence
  seed.ts          # demo data
src/
  routes/          # TanStack Start file-based routes
    login.tsx
    app.tsx                              # auth gate + server rail (+ heartbeat)
    app.me.tsx / app.me.$dmId.tsx        # DM home + conversations
    app.guild.$serverId.$channelId.tsx   # server channel view
    api/auth/$.ts                        # Better Auth request handler
  components/discord/  # ServerRail, ChannelSidebar, DMSidebar, ChatArea, MessageList, MemberList, ProfilePanel, …
  lib/             # auth-client, auth-server, formatting helpers

A learning project demonstrating Convex's real-time primitives. Not affiliated with Discord.

About

Real-time Discord-style text chat — a Convex + Better Auth + TanStack Start showcase

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages