Skip to content
Sadik-SamiPublic

About

A real time chat application with NextJs, HonoJs, PostgreSQL, Websockets, Redis and Typescript

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

SocialIO

A high-performance, real-time chat application built with a modern TypeScript stack. SocialIO features instant messaging, live presence indicators, typing indicators, image sharing, and deep WebSocket integration for a seamless user experience.

TypeScript Next.js Hono PostgreSQL Redis

✨ Core Features

  • Real-Time Messaging: Sub-millisecond message delivery via native WebSockets.
  • Live Presence & Typing: "Active now" indicators, last-seen timestamps, and real-time typing indicators powered by Redis and Zustand.
  • Optimistic UI: Messages render instantly on the client before server confirmation, ensuring a snappy feel.
  • Media Sharing: Secure, signed image uploads directly to Cloudinary.
  • Group Chats: Multi-user conversation support with admin roles and customizable group avatars.
  • Message Actions: Edit messages inline, unsend (delete) messages, and add emoji reactions.

🏗️ Architecture

SocialIO is a monorepo managed by Turborepo. The frontend is a Next.js application that communicates with a Hono backend via both REST and WebSockets.

System Overview

graph TD
    Client[Next.js Client<br/>React Query + Zustand]
    API[Hono API Gateway]
    WS[Hono WS Server]
    DB[(PostgreSQL)]
    Cache[(Redis)]
    CDN[Cloudinary]

    Client <-->|REST API| API
    Client <-->|WebSocket| WS
    API <-->|Drizzle ORM| DB
    WS <-->|Pub/Sub & Presence| Cache
    API <-->|Session State & Read-Through Cache| Cache
    Client -->|Signed Uploads| CDN
Loading

Redis operates as the central nervous system of SocialIO. For standard API requests, Hono attempts to fetch data from Redis first; if it misses, it falls back to PostgreSQL, populates the Redis cache, and returns the response. Redis also acts as the Pub/Sub broker for routing WebSocket messages across nodes and stores volatile session state.

Real-Time Message Flow

Our real-time flow is designed to avoid unnecessary database reads. The WebSocket server directly mutates the frontend's Zustand store and TanStack Query cache.

sequenceDiagram
    participant UserA as User A (Client)
    participant WS_A as WS Server (Node A)
    participant Redis as Redis PubSub
    participant WS_B as WS Server (Node B)
    participant UserB as User B (Client)
    participant DB as PostgreSQL

    UserA->>WS_A: 1. Send Message (HTTP POST)
    WS_A->>DB: 2. Insert Message
    WS_A->>Redis: 3. Publish 'new_message' event
    Redis->>WS_B: 4. Route event to Node B
    WS_B->>UserB: 5. Push 'new_message' via WS
    UserB->>UserB: 6. Mutate Zustand/React Query Cache
Loading

🚀 Tech Stack

  • Frontend: Next.js 15, React 19, TailwindCSS, shadcn/ui, TanStack Query, Zustand, Framer Motion.
  • Backend: Hono (Node.js Adapter), native ws, Better-Auth.
  • Database: PostgreSQL, Drizzle ORM.
  • Infrastructure: Redis (Pub/Sub & KV), Cloudinary (Media).

🛠️ Getting Started

Prerequisites

  • Node.js (v20+)
  • pnpm (v9+)
  • PostgreSQL
  • Redis
  • Cloudinary Account

Installation

  1. Clone the repository and install dependencies:

    pnpm install
  2. Environment Variables Setup:

    • Copy .env.example to .env in apps/server/ and configure your Postgres, Redis, and Cloudinary keys.
    • Copy .env.example to .env in apps/web/ and set your public API URLs.
  3. Apply the database schema:

    pnpm run db:push
  4. Start the development environment:

    pnpm run dev

The web application will be available at http://localhost:3001 and the API runs at http://localhost:3000.

🐳 Local Development vs Production

SocialIO uses distinct workflows for local development and production.

Local Development (Native)

We recommend running development servers natively on your machine while letting Docker handle the database and Redis infrastructure.

  1. Start the Infrastructure Run PostgreSQL and Redis in the background:

    turbo infra:start
    # or 'turbo infra:watch' to view logs
  2. Install Dependencies & Push Database Schema

    pnpm install
    turbo db:push
  3. Start the Apps Run the Next.js frontend and Hono backend with hot-reloading:

    turbo dev

Easiest Testing with Docker Compose

Run a minimal standalone production images utilizing Turborepo multi-stage pruning. The docker-compose.yml file builds isolated, non-root Alpine images for both web and server.

# Build the optimized images and start the environment
docker compose up

Then visit http://localhost:3001 to see the production build in action.

Production Deployment

Deploy minimal, standalone production images utilizing Turborepo multi-stage pruning. The docker-compose.yml file builds isolated, non-root Alpine images for both web and server.

# Build the optimized images and start the production environment
docker compose up --build -d

📁 Project Structure

socialIO/
├── apps/
│   ├── web/         # Next.js frontend application
│   └── server/      # Hono backend API & WebSocket server
├── packages/
│   ├── ui/          # Shared shadcn/ui components & Tailwind config
│   ├── auth/        # Better-Auth configuration
│   ├── db/          # Drizzle ORM schema, migrations, & Redis client
│   └── env/         # Zod-validated environment variables
└── docs/            # Architecture diagrams and planning documentation

📝 Available Scripts

  • turbo dev: Start all applications in development mode.
  • turbo dev:web: Start the Next.js frontend application.
  • turbo dev:server: Start the Hono backend API & WebSocket server.
  • turbo check-types: Check TypeScript types.
  • turbo build: Build all workspace packages and apps.
  • turbo db:start: Start a PostgreSQL database using Docker.
  • turbo db:watch: Watch the PostgreSQL database.
  • turbo db:stop: Stop the PostgreSQL database.
  • turbo db:down: Down the PostgreSQL database.
  • turbo db:generate: Generate Drizzle schema changes.
  • turbo db:migrate: Run database migrations.
  • turbo db:push: Push Drizzle schema changes to the PostgreSQL database.
  • turbo db:studio: Launch Drizzle Studio to explore your database.
  • turbo infra:start: Start the infrastructure services.
  • turbo infra:stop: Stop the infrastructure services.
  • turbo infra:down: Down the infrastructure services.
  • turbo infra:watch: Watch the infrastructure services.
  • turbo redis:ping: Ping the Redis server.
  • turbo redis:cli:: Launch the Redis CLI.

About

A real time chat application with NextJs, HonoJs, PostgreSQL, Websockets, Redis and Typescript

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages