Crit Web
May 15, 2026 · View on GitHub
The hosted share target for Crit — a local-first CLI for reviewing AI agent output with inline comments.
When you click Share in the crit CLI, your review (document + comments) is uploaded here and a public link is generated. Recipients see the full review page with inline comments, keyboard navigation, and theme switching — no install required.
Hosted version: crit.md
How it works
- You run
critlocally to review files and add inline comments - Click Share — the CLI uploads the review to crit-web
- Share the link — recipients see the full review with comments, no install required
- Unpublish from the CLI when done
Reviews auto-expire after 30 days of inactivity.
Self-Hosting
Crit Web can be self-hosted with Docker. You need PostgreSQL 17+.
Option 1: docker run (you already have PostgreSQL)
docker run -d \
-e DATABASE_URL=ecto://user:pass@your-db-host/crit_prod \
-e SECRET_KEY_BASE=$(openssl rand -base64 64 | tr -d '\n') \
-e SELFHOSTED=true \
-e PHX_HOST=localhost \
-e PHX_SERVER=true \
-p 4000:4000 \
ghcr.io/tomasz-tomczyk/crit-web:latest
Migrations run automatically on startup.
Option 2: Docker Compose (includes PostgreSQL)
cp contrib/docker-compose.example.yml docker-compose.yml
cp .env.example .env
# Edit .env — at minimum, set SECRET_KEY_BASE:
# openssl rand -base64 64 | tr -d '\n'
docker compose up -d
Visit http://localhost:4000.
Connecting the crit CLI
Point the CLI at your instance:
# Per-command
crit --share-url https://reviews.yourdomain.com path/to/files
# Or set permanently
export CRIT_SHARE_URL=https://reviews.yourdomain.com
Environment variables
| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL | Yes* | — | PostgreSQL connection URL (ecto://USER:PASS@HOST/DB) |
DB_HOST | Yes* | — | Database host — use instead of DATABASE_URL |
DB_USER | Yes* | — | Database user |
DB_PASSWORD | Yes* | — | Database password |
DB_NAME | Yes* | — | Database name |
DB_PORT | No | 5432 | Database port (only used with DB_HOST) |
DB_SSL | No | — | Set to true to enable SSL. Without DB_SSL_CA_CERT, connects encrypted without certificate verification (typical for AWS RDS) |
DB_SSL_CA_CERT | No | — | Path to a CA certificate file. When set alongside DB_SSL=true, enables full verify_peer verification (requires volume mount in Docker) |
SECRET_KEY_BASE | Yes | — | Session signing key. Generate with openssl rand -base64 64 |
SELFHOSTED | Yes | — | Set to true to enable self-hosted mode (dashboard, no marketing pages) |
LOCAL_REGISTRATION_ENABLED | No | true | Set to false to close /users/register after creating the accounts you trust |
SMTP_HOST | No | — | SMTP relay hostname. When set, password-reset and email-change confirmations are sent via SMTP; when unset, those emails go to the local Swoosh adapter |
SMTP_PORT | No | 587 | SMTP port. 465 uses implicit TLS; other ports use STARTTLS |
SMTP_USERNAME | No | — | SMTP auth username |
SMTP_PASSWORD | No | — | SMTP auth password |
SMTP_FROM | No† | — | From address for outgoing email (e.g. noreply@yourdomain.com). Required when SMTP_HOST is set |
GITHUB_CLIENT_ID | No | — | GitHub OAuth App client ID. Set with GITHUB_CLIENT_SECRET to enable GitHub login. When set, OAuth is required to access the dashboard and view reviews |
GITHUB_CLIENT_SECRET | No | — | GitHub OAuth App client secret |
OAUTH_CLIENT_ID | No | — | Generic OIDC/OAuth2 client ID for Google, GitLab, Okta, etc. Use with OAUTH_CLIENT_SECRET and OAUTH_BASE_URL. Mutually exclusive with GITHUB_CLIENT_ID |
OAUTH_CLIENT_SECRET | No | — | Generic OAuth2 client secret |
OAUTH_BASE_URL | No | — | OIDC discovery base URL, e.g. https://accounts.google.com |
PHX_HOST | No | localhost | Hostname for URL generation |
PORT | No | 4000 | HTTP listening port |
FORCE_SSL | No | false | Set true if terminating TLS at the app (not behind a reverse proxy) |
PHX_SCHEME | No | https | URL scheme for link generation |
PHX_URL_PORT | No | 443/80 | Port for generated URLs |
SENTRY_DSN | No | — | Backend Sentry DSN. When unset, no Sentry traffic is generated. Self-hosted deployments leave this blank by default |
SENTRY_FRONTEND_DSN | No | — | Browser SDK DSN. The @sentry/browser chunk is only fetched when this is set, so unset means zero third-party requests |
SENTRY_ENV | No | prod (frontend) / Mix.env() (backend) | Sentry environment tag |
SENTRY_RELEASE | No | mix.exs version | Release tag for Sentry events. The hosted Fly deploy auto-sets this to the commit SHA |
* Set either DATABASE_URL or all four of DB_HOST, DB_USER, DB_PASSWORD, DB_NAME.
| POOL_SIZE | No | 10 | Database connection pool size |
Behind a reverse proxy
The app listens on HTTP. Your reverse proxy (nginx, Caddy, Traefik) handles TLS.
PHX_HOST=reviews.yourdomain.com
PHX_SCHEME=https
PHX_URL_PORT=443
Updating
docker compose pull
docker compose up -d
Development
mix setup # Install deps, create DB, run migrations, build assets
mix phx.server # Start dev server on :4000
mix test # Run tests
mix precommit # Full CI check before submitting
See CONTRIBUTING.md for more details.
Privacy
Crit Web collects no analytics or tracking data. There is no telemetry, no usage stats, and no phone-home. If we ever add anonymous usage statistics in the future, they will be explicitly opt-in.