Two-Step Account Setup
Users sign up, then complete a profile (unique username + uploaded avatar) before accessing the protected app.
vChat is a Discord-inspired chat app built in React where users authenticate, complete a profile, add friends via requests, create DM sessions (including group DMs), and join structured community rooms with nested channels — all synchronized in real time with Firestore.
This was my first real project using React in a serious way. Up to this point, I had been building websites with pure HTML, CSS, and a separate backend. VChat marked the shift to JSX, client-side rendering, component-driven architecture, and thinking in terms of state and reactivity instead of static pages. It was also my first experience working with Firebase and truly asynchronous behavior. Managing authentication, Firestore listeners, and real-time updates forced me to understand how data flows over time — not just on page load. On top of that, I explored GSAP because I care deeply about how a product feels. This was the first time I intentionally treated motion and interaction as part of the experience, not just decoration.
Building a real-time chat product is less about UI and more about coordinating identity, relationships, and shared state across multiple clients. The challenge is creating a multi-user system (friends, DMs, rooms) that stays consistent without a custom backend server.
Authentication alone isn’t enough — users need identity (username + avatar) to participate
Friend relationships require a request/accept lifecycle, not just toggles
Chat structures should be navigable and predictable (DMs vs rooms vs channels)
Real-time sync should feel instant without manual refresh or polling
vChat uses Firebase Auth for sign-in, a required profile completion step (username + avatar), and Firestore as both the database and the real-time event stream. It supports friend requests, DM sessions (including group DMs), and room-based chat organized into main rooms and mini rooms (channels).
Users sign up, then complete a profile (unique username + uploaded avatar) before accessing the protected app.
Friend relationships are created through sent/received requests and acceptance flows, stored and synced via Firestore.
Users can create DM rooms; the UI adapts between direct conversations and group DMs (group icon + name handling).
Community rooms contain main rooms and mini rooms, where mini rooms behave like channels (text/voice types represented in the UI).
vChat is a client-driven Firebase architecture. Firestore documents model users, relationships, DMs, and rooms, while real-time listeners keep the UI synchronized. Global state lives in a UserContext that centralizes authentication, status, requests, friends, and key mutations.
Client-Heavy, Context-Centered Logic
Most mutations (requests, status updates, room operations) live in a single context layer, simplifying early development but concentrating responsibility.Document Modeling for Social Graph
Friends, requests, DM rooms, and room membership are represented as Firestore documents/subcollections enabling quick iteration.Real-Time by Default
Firestore listeners act as the event stream so UI updates propagate instantly across participants.Route-Driven App States
The app uses route structure to reflect modes: management panels (DM/room lists) vs active chat content.Early-Stage Tradeoff: Coupled UI and Data
Some Firestore operations are close to UI components, which keeps velocity high but reduces modularity for larger scaling.The UI follows a familiar chat-product mental model: a management sidebar for DMs/rooms and a primary content area for chat. Animations are used to soften transitions and make state changes feel responsive.
Discord-like two-pane layout (management panel + content panel)
Create Room modal and contextual menus for room/channel management
Search/filter patterns for DM room lists
Presence/status indicators tied to friend lists
Profile completion gate that prevents incomplete identities from entering chat
Motion for Feedback
GSAP is used for entrance/transition animations (protected content reveal and collapsible UI popups).
Clear Modes
Unprotected auth routes are separate from the protected chat experience to reduce cognitive load.
Scannable Navigation
Rooms → main rooms → channels create a predictable hierarchy for exploring conversations.
Actionable Management UI
Users can create, rename, and delete channel-like structures (where permitted), keeping the app interactive beyond messaging.
Immediate State Reflection
Requests, friends, and room membership changes are reflected through real-time updates and conditional rendering.