A federated blog platform built on ActivityPub.
x-log is an open-source, Bun + TypeScript powered blog platform that federates with the Fediverse using ActivityPub. Readers on Mastodon, Elk, Soapbox, and compatible clients can search, read, like, and follow x-log profiles and posts directly from their clients.
- Runtime: Bun
- Language: TypeScript
- API: Hono
- Validation: Zod + zod-to-openapi
- Database: PostgreSQL + Kysely
- Frontend: Next.js (App Router) + TailwindCSS
- Monorepo: Turborepo
- Queue: Redis + Worker (Bun)
- Deployment: Docker Compose
- Bun >= 1.0.0
- Docker and Docker Compose
- PostgreSQL 16
- Redis 7
- Install dependencies:
bun install- Set up environment variables:
# For local development (outside Docker)
cp .env.example .env
# Edit .env with your settings
# OR for Docker Compose
cp infra/compose/.env.example infra/compose/.env
# Edit infra/compose/.env with your settings- Set up environment file:
make setup
# Or manually:
cp infra/compose/.env.example infra/compose/.env
# Edit infra/compose/.env with your settings- Start services with Docker Compose:
For development with hot-reload/watch mode (recommended):
make dev
# Or with Docker Compose watch (requires Docker Compose v2.22+):
make dev-watchFor production-like setup:
make up- Run migrations:
make migrate
# Or manually:
cd apps/api && bun run migratemake dev- Start development environment with Bun watch modemake dev-watch- Start development environment with Docker Compose watchmake dev-stop- Stop development environmentmake migrate- Run database migrationsmake logs- View logs from all servicesmake clean- Remove containers, volumes, and imagesmake help- Show all available commands
The repo now includes an Expo mobile app in apps/mobile.
Useful commands:
bun run mobile- Start the Expo development serverbun run mobile:ios- Run the mobile app on iOSbun run mobile:android- Run the mobile app on Android
Environment variables:
EXPO_PUBLIC_API_BASE_URL- Direct backend API URL for native clients, for examplehttp://localhost:8080/apiEXPO_PUBLIC_EAS_PROJECT_ID- EAS project ID used for release builds
When running make dev, the following services will be available:
- API server on http://localhost:8080 (internal, not exposed in production)
- Web server on http://localhost:3000 (public-facing)
- Worker service (background jobs)
- PostgreSQL on localhost:5432
- Redis on localhost:6379
All API requests are proxied through Next.js SSR routes. In production, only the Next.js server is exposed to the internet, and it internally communicates with the backend API server.
Environment Variables:
BACKEND_API_URL- Internal URL to the backend API server (defaults toNEXT_PUBLIC_API_URLorhttp://localhost:8080)NEXT_PUBLIC_API_URL- Fallback for backend API URL (used in development)
API Flow:
- Frontend makes requests to
/api/*(Next.js routes) - Next.js API routes proxy requests to the backend API server
- Backend API server processes requests and returns responses
- Next.js forwards responses back to the frontend
This architecture ensures:
- Backend API is not directly exposed to the internet
- Session cookies are properly forwarded
- CORS issues are avoided
- Single entry point for all API requests
x-log/
βββ apps/
β βββ api/ # Hono API server
β βββ mobile/ # Expo + React Native mobile app
β βββ web/ # Next.js frontend
β βββ worker/ # Background job worker
βββ packages/
β βββ db/ # Kysely database client and schema
β βββ validation/ # Zod schemas
β βββ ap/ # ActivityPub helpers
β βββ snowflake/ # Snowflake ID generator
β βββ config/ # Shared configuration
β βββ ui/ # Shared UI components
β βββ types/ # Shared TypeScript types
βββ infra/
βββ compose/ # Docker Compose configuration
AGPL-3.0 (to be confirmed)
Tagging a commit with mobile-v<version> triggers .github/workflows/mobile-release.yml.
Example:
git tag mobile-v1.0.0
git push origin mobile-v1.0.0Required GitHub secrets:
EXPO_TOKENEXPO_PUBLIC_EAS_PROJECT_ID