Rybbit Analytics: Self-Hosted Web & Product Analytics

Rybbit is a modern, open-source alternative to Google Analytics—built for privacy, extensibility, and full control.

Rybbit Project Overview

Rybbit Analytics provides comprehensive web and product analytics without third-party cookies or data sharing.

It splits responsibilities across:

  • Client: A Next.js dashboard and UI built in TypeScript & React
  • Server: A Fastify-based Node.js API for ingestion, querying, and auth
  • Databases: ClickHouse for event storage; PostgreSQL (via Drizzle ORM) for metadata
  • Tracker: A lightweight JavaScript snippet to collect pageviews, events, and user sessions

Why Rybbit Matters 🚀

  • Privacy First: No cookies or personal tracking; GDPR & CCPA compliant
  • Self-Hosted: Full ownership of your data—run anywhere, on any VPS or cloud
  • Performance: ClickHouse powers real-time dashboards and high-volume queries
  • Extensibility: Custom events, funnels, goals, and integrations out of the box

Key Features

  • 📈 Real-time dashboards (sessions, users, pageviews)
  • 👥 User journeys & funnels for conversion analysis
  • 🥅 Custom goals with path or event-based triggers
  • 🔁 Retention cohorts and returning user insights
  • 🗺️ Geo-tracking (country → region → city) and map visualizations
  • 🚫 No cookies or fingerprinting—strictly privacy compliant
  • ⚙️ Multi-organization & multi-site support
  • 🐳 Docker Compose & Caddy-ready for one-command deploys
  • 📜 Open source (AGPL-3.0 license)

Modules at a Glance

  1. client/ – Next.js 15 dashboard (React, Tailwind CSS, @tanstack/react-query, Nivo)
  2. server/ – Fastify API (TypeScript, @clickhouse/client, fastify-cors, better-auth)
  3. src/db/ – Drizzle ORM schemas (PostgreSQL) & ClickHouse init scripts
  4. src/tracker/ – JS snippet to capture and POST events (/track endpoint)
  5. cron/ – Scheduled jobs (e.g., subscription checks, session cleanup)
  6. lib/ – Utilities for auth, site config, allowed domains

Dependencies

  • Client: Next.js, React, Tailwind CSS, Framer Motion, Nivo Charts, React Query, Zustand
  • Server: Fastify, Drizzle ORM, @clickhouse/client, pg, postgres, dotenv, luxon, node-cron, Stripe SDK
  • Infrastructure: Docker, Docker Compose, Caddy (reverse proxy & TLS)

Configuration & Environment

Rybbit uses environment variables to configure database connections, auth, and host settings.

Common variables ⚙️:

POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB=analytics
POSTGRES_USER=frog
POSTGRES_PASSWORD=frog

CLICKHOUSE_HOST=http://clickhouse:8123
CLICKHOUSE_DB=analytics
CLICKHOUSE_PASSWORD=frog

BASE_URL=https://analytics.example.com
BETTER_AUTH_SECRET=<long-random-string>
DISABLE_SIGNUP=false
DOMAIN_NAME=analytics.example.com

Static Code Analysis

  • Languages: TypeScript, JavaScript, Bash
  • Structure: Monorepo with client/, server/, docs/, scripts, and config at root
  • Code Quality: Drizzle ORM for type-safe schemas; extensive unit & integration points in API

Deployment 🐳

Quickstart with Docker Compose

  1. Clone the repo and set up your .env file using the example or above template.
  2. Run docker-compose up -d to launch ClickHouse, PostgreSQL, Caddy, server, and client.
  3. Access your analytics dashboard at http(s)://<DOMAIN_NAME>.
git clone https://github.com/rybbit-io/rybbit
cd rybbit

#docker-compose up -d
sudo docker compose up -d
#docker-compose -f rybbit_docker-compose.yml up -d

To understand what’s going on in rybbit_docker-compose.yml you can have a closer look.

It spins up a full Rybbit stack consisting of:

  1. caddy • Reverse-proxy (with automatic HTTPS via Let’s Encrypt) and HTTP/3 support • Listens on 80, 443 (TCP) and 443/UDP (QUIC) • Mounts your local Caddyfile (./Caddyfile) plus two named volumes to persist certs and Caddy’s runtime config • Reads DOMAIN_NAME from your environment (used in your Caddyfile) • Depends on both backend and client so that you don’t get TLS errors on first start
  2. clickhouse • The analytics database (very fast columnar store) • Exposes 8123 (HTTP) and 9000 (native TCP) • Persists data to clickhouse-data and reads extra config from ./clickhouse_config/ • Takes CLICKHOUSE_DB, CLICKHOUSE_USER, CLICKHOUSE_PASSWORD from your env (with sensible defaults) • Has a simple HTTP health-check so Docker won’t route traffic until ClickHouse is ready
  3. postgres • Stores user-management data (accounts, project metadata, etc.) • Exposes the normal Postgres port via a named volume postgres-data • Configured via POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB (env defaults to “frog”/“analytics”)
  4. backend • The Rybbit server (Node.js/Koa) • Built from ./server/Dockerfile or pulled from ghcr.io/rybbit-io/rybbit-backend:${IMAGE_TAG:-latest} • Reads: – Database endpoints: CLICKHOUSE_HOST, POSTGRES_HOST/PORT/etc. – Secrets & flags: BETTER_AUTH_SECRET, BASE_URL, DISABLE_SIGNUP • Exposes whatever you set in HOST_BACKEND_PORT (e.g. “4000:4000”) • Won’t start until ClickHouse is healthy and Postgres is up
  5. client • The React/Next.js front-end • Built from ./client/Dockerfile or pulled from ghcr.io/rybbit-io/rybbit-client:${IMAGE_TAG:-latest} • Build-time args & runtime env: – NEXT_PUBLIC_BACKEND_URL = ${BASE_URL} – NEXT_PUBLIC_DISABLE_SIGNUP = ${DISABLE_SIGNUP} • Exposes whatever you set in HOST_CLIENT_PORT (e.g. “3000:3000”) • Depends on the backend so pages don’t 404 on first load

Volumes • clickhouse-data, postgres-data • caddy_data (Let’s Encrypt certs & ACME state) • caddy_config (Caddy’s internal config cache)

Manual Setup (Without Docker)

  1. Run ./setup.sh to install and configure dependencies.
  2. Launch services:
    • ./start.sh to start server & client
    • ./stop.sh to stop all services
    • ./update.sh to pull latest changes and rebuild

Rybbit Releases

  • 🚀 v0.2.0 (2025-05-14)
  • Refactored analytics event handling: standardized naming & payload structure
  • Enhanced UI components (EventList, Pages) with configurable truncation & styling
  • Performance improvements in site cards and chart rendering
  • Updated Docker Compose defaults & port mappings; improved cloud readiness
  • Increased trial event limit to 1,000,000 events
  • ✨ v0.1.4 (2025-05-11)
  • Added integrations: WordPress, Webflow, Shopify, Framer
  • Simplified time handling in getOverviewBucketed and chart utilities
  • Fixed mobile layout issues in activity calendar and realtime page
  • 📦 Earlier Releases (v0.1.0 – v0.1.3)
  • v0.1.3: Refined bucket selection & time parameter handling in analytics APIs
  • v0.1.2: Bug fixes, mockdata improvements, and layout tweaks
  • v0.1.1: Minor UI enhancements and performance optimizations
  • v0.1.0: Initial public release—core analytics (sessions, pageviews, users, events)

For detailed changelogs and upgrade steps, see the GitHub Releases page.


Ready to take back control of your data? Start exploring Rybbit Analytics today! 🚀