Operate
Self-hosting
Run the web app, API, and worker yourself.
OpenMerge is open source under the MIT license. The code is on GitHub, and this page covers what you need to run it yourself.
Architecture
| Service | Role |
|---|---|
apps/web | Next.js app: landing page, docs, sign-in, and dashboard. |
apps/server | Express API: GitHub OAuth, webhook verification, review sessions, and dashboard routes. Queues review jobs. |
apps/worker | Processes review jobs: gathers context, runs the agents, and posts to GitHub. Run it separately from the API. |
| PostgreSQL | Users, installations, repositories, review sessions, and findings. |
| Redis | The review job queue. |
Create a GitHub App
Create a GitHub App for your deployment, plus an OAuth app for dashboard sign-in, and point them at your URLs:
| Setting | Value |
|---|---|
| Webhook URL | https://<api-host>/api/v1/webhook/github |
| Webhook events | Pull request and Installation |
| Setup URL | https://<web-host>/setup |
| OAuth callback URL | https://<web-host>/auth/github/callback |
The app needs to read repository contents and pull requests and to write pull request comments. Generate a private key and a webhook secret, and keep both in your secret manager.
Environment variables
The API validates its environment at startup and exits with a clear error if something is missing. It reads apps/server/.env or a .env at the repository root.
API and worker
| Variable | Status | Description |
|---|---|---|
DATABASE_URL | Required | PostgreSQL connection string. |
SERVER_JWT_SECRET | Required | Signs dashboard sessions (valid for seven days). |
GITHUB_CLIENT_ID | Required | OAuth app client ID, used for sign-in. |
GITHUB_CLIENT_SERVER | Required | OAuth app client secret. |
GITHUB_CALLBACK_URL | Required | The web app's /auth/github/callback URL. |
GITHUB_APP_ID | Required | GitHub App ID. |
GITHUB_APP_NAME | Required | GitHub App slug. |
GITHUB_APP_CLIENT_ID | Required | GitHub App client ID. |
GITHUB_APP_CLIENT_SECRET | Required | GitHub App client secret. |
GITHUB_WEBHOOK_SECRET | Required | Verifies X-Hub-Signature-256 on incoming webhooks. |
GITHUB_PRIVATE_KEY | Required | GitHub App private key (PEM). |
GROQ_API_KEY | Required | Model provider used for reviews, and the fallback when Gemini is configured. |
GEMINI_API_KEY | Optional | When set, Gemini is tried first and Groq is used as the fallback. |
REDIS_URL | Optional | Defaults to redis://localhost:6379 in development. Required in production. |
PORT | Optional | API port. Defaults to 8000. |
Web app
| Variable | Status | Description |
|---|---|---|
NEXT_PUBLIC_API_URL | Required | Public URL of the API. Defaults to http://localhost:8000. |
NEXT_PUBLIC_APP_URL | Required | Public URL of the web app. |
Allow your web origin
apps/server/src/index.ts. Add your web app's URL there, or the dashboard cannot reach the API.Local development
You need Bun and Docker. Start PostgreSQL and Redis, install dependencies, apply migrations, and run everything in watch mode:
docker compose up -d # PostgreSQL on 5433, Redis on 6379
bun install
cd packages/database && bun run db:migrate:dev && cd ../..
bun run dev # web, API, and workerDATABASE_URL at localhost:5433.To run a single app, filter by workspace:
bun run dev --filter=web
bun run dev --filter=server
bun run dev --filter=workerProduction checklist
- Run the API and the worker as separate, independently restartable services.
- Use managed PostgreSQL and Redis with persistent storage and backups.
- Set
NEXT_PUBLIC_APP_URL,NEXT_PUBLIC_API_URL, andGITHUB_CALLBACK_URLto their public HTTPS addresses. - Apply migrations on each deploy with
bun --cwd packages/database run db:migrate:deploy. - Add health checks, structured logs, queue monitoring, and alerts for failed jobs.
- Rotate any exposed private key, webhook secret, OAuth secret, or model key immediately.
Something unclear or out of date? Open an issue.