A production-grade URL shortener with analytics, tags, and QR code generation. Built with Go + React, designed for solo founders and SaaS teams.
Backend: Go 1.25, chi, sqlc, PostgreSQL, ClickHouse, Redis, Clerk
Frontend: React 19, TypeScript, Vite, TanStack Router, TanStack Query, Tailwind CSS 4, Radix UI
Infra: Docker Compose
- Create short links with auto-generated or custom shortcodes
- Tag management — create, assign, filter links by tags
- Click analytics — clicks over time, top referrers, user agents (ClickHouse)
- QR code generation per link
- Redis caching for fast redirects
- Clerk authentication (Google/GitHub OAuth)
- Request IDs, structured production logging, security headers, rate limiting, health checks
- Dark/light mode, responsive UI
# Clone and enter the project
git clone <repo-url> && cd url-shortener
# Set Clerk API keys (get them from https://dashboard.clerk.com)
export CLERK_SECRET_KEY=sk_test_...
export VITE_CLERK_PUBLISHABLE_KEY=pk_test_...
# Start the local development stack
docker compose up --buildOpen http://localhost:5173, sign in with Google/GitHub, and start shortening URLs.
server/ # Go backend
client/ # React frontend
docs/ # Architecture, onboarding, code reviews
docker-compose.yml
See docs/WELCOME.md for a full developer onboarding guide. See docs/DEPLOYMENT.md for MVP deployment instructions.
| Method | Path | Description |
|---|---|---|
GET |
/{shortcode} |
Redirect |
GET |
/api/v1/health/live |
Liveness check |
GET |
/api/v1/health/ready |
Dependency readiness check |
POST |
/api/v1/links |
Create link |
GET |
/api/v1/links |
List links |
GET |
/api/v1/links/{shortcode}/analytics |
Analytics |
GET |
/api/v1/links/{shortcode}/qrcode |
QR code |
Full API reference at http://localhost:8080/api/v1/reference
Operational headers:
X-Request-IDis returned on every response and included in production logs.X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset, andRetry-Afterdescribe rate-limit state.
docker-compose.yml is intentionally a development compose. It starts Postgres, Redis, ClickHouse, the API, and the web client for local work.
For self-hosting on a VPS with Coolify or Dokploy, deploy the app as two separate services:
- Backend: build from
server/Dockerfile - Frontend: build from
client/Dockerfile
Use the repository root as the Docker build context for both services.
# Start dependencies
docker compose up postgres redis clickhouse -d
# Run server (with hot reload)
cd server && cp .env.example .env
task run
# Run client
cd client && pnpm install && pnpm devGitHub Actions runs backend tests, frontend checks, and OpenAPI YAML validation on pushes to main and pull requests.
MIT