Skip to content

Open source community platform — self-hosted Discord + Reddit alternative built in TypeScript.

License

Notifications You must be signed in to change notification settings

CodesWhat/concord

concord

concord

Open source community platform — self-hosted Discord alternative built in TypeScript.

Version License AGPL-3.0 Status

Stars Forks Issues Last commit


Concord is a self-hosted, open-source Discord alternative. Familiar enough to feel like home, better enough to justify the switch. One docker compose up to own your community's data. AGPL-3.0, no CLA.


Screenshots coming soon — in the meantime, try docker compose -f docker/docker-compose.yml up -d and see for yourself!


Contents



What is Concord?

Concord is a self-hosted, open-source community platform built as a drop-in Discord replacement. Run it on your own server in minutes with a single docker compose up. You own your data, your community, and your future — no vendor lock-in, no data mining, no proprietary walls.

It ships with real-time chat, forum channels (Reddit-style), file uploads, role-based permissions, push notifications, and more. AGPL-3.0 licensed with no CLA — your contributions stay yours and can never be relicensed.



Quick Start (Self-Host)

Prerequisites: Docker and Docker Compose.

git clone https://github.com/CodesWhat/concord.git
cd concord
docker compose -f docker/docker-compose.yml up -d

Then open http://localhost:8080. The database migrates automatically on startup. Register a new account to get started — the first user to create a server becomes its owner.

S3 storage setup (Garage)

The Docker Compose stack includes Garage for S3-compatible file storage. After first start, create the bucket:

# Connect to the Garage admin API and set up the cluster
docker compose -f docker/docker-compose.yml exec garage /garage node id 2>/dev/null | head -1
# Use the node ID from above:
docker compose -f docker/docker-compose.yml exec garage /garage layout assign -z dc1 -c 1G <NODE_ID>
docker compose -f docker/docker-compose.yml exec garage /garage layout apply --version 1

# Create an API key and bucket
docker compose -f docker/docker-compose.yml exec garage /garage key create concord-key
docker compose -f docker/docker-compose.yml exec garage /garage bucket create concord
docker compose -f docker/docker-compose.yml exec garage /garage bucket allow concord --read --write --key concord-key

Update the S3_ACCESS_KEY and S3_SECRET_KEY in docker/docker-compose.yml with the key ID and secret from the key create output.

Optional configuration: For Docker, edit the environment variables directly in docker/docker-compose.yml. For local development, copy apps/api/.env.example to apps/api/.env. Set your SMTP credentials for email delivery, S3 details for file uploads, and VAPID keys for push notifications. See the Configuration section for all available variables.



Features

Chat & Messaging
  • Real-time messaging — WebSocket gateway with instant delivery, edit, delete, and "(edited)" tags
  • Threads — Threaded replies within channels
  • Typing indicators — Animated "X is typing..." bar with 8-second auto-expire
  • Presence tracking — Live online/idle/DND/invisible status synced across all clients
  • Markdown rendering — Code blocks, links, lists, tables, task lists via react-markdown
  • Unread tracking — Per-channel unread counts with mention badges
  • Slowmode — Per-channel message rate limiting enforced server-side
Files & Media
  • File uploads — Drag and drop, paste, or click to upload; S3-backed storage
  • Avatar upload — User profile avatars stored in S3
Forum Channels
  • Reddit-style forums — Forum channel type alongside text channels
  • Voting — Upvote/downvote posts with live vote counts
  • Comments — Nested comments on forum posts
  • Post management — Create, edit, and delete forum posts
Roles & Permissions
  • Role-based permissions — Bitmask permission system with named roles
  • Channel overrides — Per-channel permission overrides per role
  • Role hierarchy — Enforcement prevents users from acting above their role
  • Kick & ban — Kick or ban members with hierarchy checks; ban list with unban support
Servers & Invites
  • Server management — Create, join, edit, and delete servers
  • Invite links — Shareable invite codes with configurable expiry and usage limits
  • Leave server — Members can leave servers; wrapped in a transaction for safety
Notifications & Communication
  • Push notifications — Web Push for @mentions; works on desktop and mobile
  • Password reset — Email-based forgot-password flow via configurable SMTP
User Experience
  • User profiles — Bio, avatar, display name, status
  • Quick switcher — Cmd+K fuzzy search across servers and channels
  • PWA installable — Install as a native app on desktop and mobile
  • Responsive UI — 4-panel desktop layout with mobile-optimized bottom navigation
Operations
  • Auto-migration — Database migrations run automatically on API startup
  • Rate limiting — Global and per-route rate limits via @fastify/rate-limit
  • S3-compatible storage — Works with MinIO, Cloudflare R2, AWS S3, or any compatible provider


Configuration

For Docker deployments, set these in docker/docker-compose.yml. For local development, copy apps/api/.env.example to apps/api/.env:

Variable Description
DATABASE_URL PostgreSQL connection string
REDIS_URL Redis connection string
AUTH_SECRET Secret for session/auth token signing (required)
CORS_ORIGIN Allowed frontend origin (e.g. https://concord.example.com)
SMTP_HOST SMTP server host for email delivery
SMTP_PORT SMTP server port (typically 587 or 465)
SMTP_USER SMTP username
SMTP_PASS SMTP password
SMTP_FROM From address for outgoing emails
S3_ENDPOINT S3-compatible storage endpoint (e.g. https://s3.amazonaws.com)
S3_BUCKET Storage bucket name
S3_ACCESS_KEY Storage access key
S3_SECRET_KEY Storage secret key
VAPID_PUBLIC_KEY VAPID public key for Web Push notifications
VAPID_PRIVATE_KEY VAPID private key for Web Push notifications
VAPID_SUBJECT VAPID subject (e.g. mailto:admin@example.com)


Development

Prerequisites: Node.js 22+, pnpm 10+, Docker (for Postgres, Redis, and MinIO)

# Clone
git clone https://github.com/CodesWhat/concord.git
cd concord

# Install dependencies
pnpm install

# Start database services
docker compose -f docker/docker-compose.dev.yml up -d

# Copy environment config
cp apps/api/.env.example apps/api/.env

# Run database migrations
cd apps/api && pnpm drizzle-kit push && cd ../..

# Seed sample data (optional)
cd apps/api && pnpm tsx src/seed.ts && cd ../..

# Start development servers
pnpm dev

Then open http://localhost:5173 — the API runs on port 3000, proxied through Vite.

# Run all apps in dev mode (web + api)
pnpm dev

# Build all packages
pnpm build

# Run database migrations
cd apps/api && pnpm drizzle-kit push

# Generate a new migration
cd apps/api && pnpm drizzle-kit generate
Project conventions
  • Small, single-purpose files — No file exceeds ~300 lines
  • Explicit types — No any, typed parameters and return types everywhere
  • One route per fileroutes/messages.ts handles all message endpoints
  • Service layer separation — Routes handle HTTP, services handle business logic
  • ServiceResult<T> pattern{ data, error } tuples instead of thrown exceptions
  • Colocated testsroutes/messages.tsroutes/messages.test.ts


Architecture

Turborepo monorepo with three packages:

concord/
├── apps/
│   ├── web/          # React 19 + Vite 6 + Tailwind CSS v4
│   └── api/          # Fastify 5 + Drizzle ORM + WebSocket gateway
├── packages/
│   ├── shared/       # Shared types, permissions, snowflake utilities
│   └── config/       # Shared ESLint + TypeScript config
└── docker/           # Docker Compose for dev and production
Layer Technology
Frontend React 19, Vite 6, Tailwind CSS v4, Zustand
Backend Fastify 5, TypeScript, Drizzle ORM
Database PostgreSQL 17, Redis 7
Auth Better Auth (session-based, Drizzle adapter)
Real-time WebSocket (ws), Redis pub/sub for fan-out
IDs Snowflake (64-bit, custom epoch 2026-01-01)
Storage S3-compatible (MinIO, AWS S3, Cloudflare R2)


Contributing

Contributions are welcome. See CONTRIBUTING.md for setup instructions, code style, and the PR process.

This project is AGPL-3.0 with no CLA — your contributions can never be relicensed.



License

AGPL-3.0 — no CLA. By contributing, you agree your contributions will be licensed under the same terms. Your code stays yours.



About

Open source community platform — self-hosted Discord + Reddit alternative built in TypeScript.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

  •  

Packages

No packages published

Contributors 2

  •  
  •  

Languages