A modern, real-time collaborative chat platform built with Effect-TS, ElectricSQL, TanstackDB, React, and PostgreSQL.
Hazel Chat is a full-stack chat application featuring:
- Effect-TS for type-safe, functional backend programming
- Type-safe RPC for seamless client-server communication
- Local-first architecture with Electric SQL for real-time sync
- Distributed workflows via Effect Cluster for background jobs
- Real-time Messaging - Channels and direct messages with instant delivery
- User Presence - Live online/offline status and typing indicators
- Message Reactions - React to messages with emoji
- Pinned Messages - Save important messages for quick access
- File Attachments - Share files with Cloudflare R2 storage
- Notifications - Configurable notification system with muting
- Team Management - Organizations with member roles and invitations
- Rich Text Editor - Plate.js powered editor with formatting
- Bot Integration - Create and manage bots with a simple API
- React 19 with TypeScript
- Vite for fast development and builds
- TanStack Router with file-based routing
- TanStack DB
- TailwindCSS v4
- React Aria Components
- Electric SQL for local-first real-time sync
- Bun runtime
- Effect-TS functional programming framework
- Effect RPC for type-safe APIs
- Drizzle ORM with PostgreSQL
- WorkOS for authentication
- Effect Cluster for distributed systems
- Effect Workflow for durable background jobs
- PostgreSQL-backed persistence
- Turborepo for monorepo orchestration
- OXC for linting and formatting
- Vitest for testing
├── apps/
│ ├── web/ # React frontend (port 3000)
│ ├── backend/ # Effect-TS API server (port 3003)
│ ├── cluster/ # Distributed workflow service (port 3020)
│ ├── electric-proxy/ # Electric SQL proxy worker
│ └── link-preview-worker/ # Link preview generation
├── packages/
│ ├── db/ # Drizzle ORM schemas and migrations
│ ├── domain/ # Shared types, RPC contracts, cluster definitions
│ ├── backend-core/ # Reusable backend services and repositories
│ ├── schema/ # Shared schema definitions
│ └── ...
└── .context/ # Library documentation (Effect, Effect Atom, TanStack DB)
-
Clone the repository
git clone <repository-url> cd app
-
Install dependencies
bun install
-
Set up environment variables
Create
.envfiles in the relevant apps. Key variables include:apps/web/.env
VITE_BACKEND_URL=http://localhost:3003 VITE_CLUSTER_URL=http://localhost:3020 VITE_WORKOS_CLIENT_ID=<your-workos-client-id> VITE_WORKOS_REDIRECT_URI=http://localhost:3000/callback VITE_ELECTRIC_URL=<electric-sql-url>apps/backend/.env
DATABASE_URL=postgresql://user:password@localhost:5432/maki_chat WORKOS_API_KEY=<your-workos-api-key> WORKOS_COOKIE_PASSWORD=<32-character-secret>apps/cluster/.env
DATABASE_URL=postgresql://user:password@localhost:5432/maki_chat -
Run database migrations
cd packages/db bun run db push -
Start development
bun run dev
This starts all apps via Turborepo:
- Web: http://localhost:3000
- Backend: http://localhost:3003
- Cluster: http://localhost:3020
| Command | Description |
|---|---|
bun run dev |
Start all apps in development mode |
bun run build |
Build all apps and packages |
bun run typecheck |
Run TypeScript checking across all packages |
bun run format |
Format and lint code with OXC |
bun run test |
Run tests in watch mode |
bun run test:once |
Run all tests once |
bun run test:coverage |
Run tests with coverage report |
The backend uses Effect-TS for:
- Dependency injection via layers and services
- Error handling with typed errors
- Resource management with scoped resources
- Concurrency with fibers and streams
Type-safe client-server communication using Effect RPC:
- Contracts defined in
packages/domain - Full type inference across the boundary
- Automatic serialization/deserialization
Electric SQL provides local-first data synchronization:
- Optimistic updates with automatic conflict resolution
- Offline support with background sync
- Reactive queries via TanStack Query integration
Effect Cluster handles background jobs:
- Durable workflow execution
- Automatic retries and failure handling
- PostgreSQL-backed persistence
- CLAUDE.md - Detailed architecture and development guidelines
- packages/db/README.md - Database schema documentation
- .context/ - Library-specific guides for Effect, Effect Atom, and TanStack DB
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run formatting (
bun run format:fix) - Run tests (
bun run test:once) - Commit your changes
- Push to your branch
- Open a Pull Request
This project uses OXC for formatting and linting:
- Tab indentation
- Double quotes
- Trailing commas
- 110 character line width
Run bun run format before committing.
See LICENSE for details.