{"id":47680882,"url":"https://github.com/carvalhocaio/link-arch","last_synced_at":"2026-06-16T04:01:06.019Z","repository":{"id":345201467,"uuid":"1184880660","full_name":"carvalhocaio/link-arch","owner":"carvalhocaio","description":"A fast, lightweight URL shortener API built with Bun and Elysia. It generates short links, tracks click counts, validates target URL reachability, and exposes auto-generated OpenAPI documentation.","archived":false,"fork":false,"pushed_at":"2026-03-20T03:57:15.000Z","size":897,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T01:45:06.549Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/carvalhocaio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-18T02:46:08.000Z","updated_at":"2026-03-20T03:57:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/carvalhocaio/link-arch","commit_stats":null,"previous_names":["carvalhocaio/url-shortener","carvalhocaio/link-arch"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/carvalhocaio/link-arch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carvalhocaio%2Flink-arch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carvalhocaio%2Flink-arch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carvalhocaio%2Flink-arch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carvalhocaio%2Flink-arch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/carvalhocaio","download_url":"https://codeload.github.com/carvalhocaio/link-arch/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carvalhocaio%2Flink-arch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34390052,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-02T13:59:20.038Z","updated_at":"2026-06-16T04:01:06.007Z","avatar_url":"https://github.com/carvalhocaio.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Link Arch\n\nLink Arch is a fast, lightweight link management platform built with Bun, Elysia, and Next.js. It supports authenticated URL shortening, custom aliases, click tracking, URL lifecycle management, and auto-generated OpenAPI docs.\n\n## Features\n\n- Authenticated link management with Google sign-in (Better Auth OAuth)\n- Create short URLs with custom keys or generated aliases\n- URL reachability validation before creating or updating links\n- Link administration: update destination, update key, toggle active status, set expiry date, and soft delete\n- Redirect and non-redirect preview (`/:key/peek`) endpoints\n- Dashboard and My Links UI with search, filtering, sorting, pagination, and CSV export\n- OpenAPI documentation generated directly from route schemas\n\n## Tech Stack\n\n### Backend\n\n- **Runtime:** [Bun](https://bun.sh)\n- **Framework:** [Elysia](https://elysiajs.com)\n- **Auth:** [Better Auth](https://www.better-auth.com)\n- **Database:** PostgreSQL\n- **ORM:** [Drizzle ORM](https://orm.drizzle.team) (with [postgres.js](https://github.com/porsager/postgres) driver)\n\n### Frontend\n\n- **Framework:** [Next.js](https://nextjs.org) 16 (App Router, Turbopack)\n- **UI Components:** [shadcn/ui](https://ui.shadcn.com) v4\n- **Data Fetching:** [TanStack React Query](https://tanstack.com/query) v5\n- **Theming:** [next-themes](https://github.com/pacocoursey/next-themes) (system, light, dark)\n- **Notifications:** [Sonner](https://sonner.emilkowal.dev)\n\n### Tooling\n\n- **Monorepo:** [Turborepo](https://turbo.build)\n- **Linter/Formatter:** [Biome](https://biomejs.dev)\n- **Load Testing:** [k6](https://k6.io)\n\n## Prerequisites\n\n- [Bun](https://bun.sh) v1.2.0+\n- [PostgreSQL](https://www.postgresql.org) running locally or remotely\n- [k6](https://k6.io) (optional, for load testing)\n\n## Getting Started\n\n### 1. Clone the repository\n\n```bash\ngit clone https://github.com/carvalhocaio/link-arch.git\ncd link-arch\n```\n\n### 2. Install dependencies\n\n```bash\nbun install\n```\n\n### 3. Configure environment variables\n\n```bash\ncp .env.example .env\n```\n\nSet values in `.env`:\n\n| Variable | Description | Default |\n|---|---|---|\n| `DATABASE_URL` | PostgreSQL connection string used by API and migrations | _(required)_ |\n| `PORT` | API server listen port | `3000` |\n| `BASE_URL` | Public API base URL used to build short links | `http://localhost:3000` |\n| `WEB_URL` | Allowed web origin for CORS and trusted auth origins | `http://localhost:3001` |\n| `FORWARD_TIMEOUT_MS` | Timeout in milliseconds for URL reachability checks | `5000` |\n| `BETTER_AUTH_SECRET` | Better Auth signing secret | _(required)_ |\n| `GOOGLE_CLIENT_ID` | Google OAuth 2.0 client ID | _(required)_ |\n| `GOOGLE_CLIENT_SECRET` | Google OAuth 2.0 client secret | _(required)_ |\n| `NEXT_PUBLIC_API_URL` | API base URL consumed by the Next.js app | `http://localhost:3000` |\n\n\u003e Create the Google OAuth credentials in the [Google Cloud Console](https://console.cloud.google.com/apis/credentials) (type: Web application) and set the authorized redirect URI to `\u003cBASE_URL\u003e/api/auth/callback/google`.\n\n### 4. Run database migrations\n\n```bash\nbun run db:generate\nbun run db:migrate\n```\n\n### 5. Start development\n\n```bash\nbun run dev\n```\n\nBy default:\n\n- API: `http://localhost:3000`\n- Web: `http://localhost:3001`\n\nYou can also run only one app:\n\n```bash\nbun run dev:api\nbun run dev:web\n```\n\n## Available Scripts\n\nRun all commands from the monorepo root with `bun run \u003cscript\u003e`.\n\n| Script | Description |\n|---|---|\n| `dev` | Start all apps in development mode |\n| `dev:api` | Start only the API app |\n| `dev:web` | Start only the web app |\n| `build` | Build all apps and packages |\n| `lint` | Run lint tasks in workspaces |\n| `check` | Run Biome checks in workspaces |\n| `test` | Run test tasks in workspaces |\n| `format` | Format repository files with Biome |\n| `db:generate` | Generate Drizzle migration files |\n| `db:migrate` | Apply pending migrations |\n\n## Project Structure\n\nThis repository is a Turborepo monorepo:\n\n- `apps/api` - Elysia API (shorten, redirect, auth, admin, OpenAPI)\n- `apps/web` - Next.js frontend (landing page, dashboard, my-links, login)\n- `packages/db` - Shared Drizzle schema, auth schema, and migration scripts\n- `packages/biome-config` - Shared Biome configuration\n- `packages/tsconfig` - Shared TypeScript configuration\n\n## API Overview\n\nCommon routes include:\n\n- `GET /health` - Health and metadata\n- `POST /api/auth/sign-in/social` - Start Google OAuth sign-in (returns redirect URL)\n- `GET /api/auth/callback/google` - Google OAuth callback (handled by Better Auth)\n- `GET /api/auth/get-session` - Current user session\n- `POST /api/auth/sign-out` - End session\n- `POST /api/shorten` - Create short URL (authenticated)\n- `GET /:key` - Redirect to target URL\n- `GET /:key/peek` - Preview URL metadata without redirect\n- `GET /api/admin/urls` - List current user URLs (authenticated)\n- `PATCH /api/admin/urls/:id` - Update destination URL and expiry (authenticated)\n- `PATCH /api/admin/urls/:id/key` - Update short key (authenticated)\n- `PATCH /api/admin/urls/:id/status` - Activate/deactivate link (authenticated)\n- `DELETE /api/admin/urls/:id` - Soft delete link (authenticated)\n\n## API Documentation\n\nThe API is fully documented via auto-generated OpenAPI.\n\nOnce the API is running:\n\n```http\nGET /openapi\n```\n\nYou can import this spec into tools like [Swagger UI](https://swagger.io/tools/swagger-ui/) or [Scalar](https://scalar.com).\n\n## Architecture\n\nSee [ARCHITECTURE.md](ARCHITECTURE.md) for a detailed breakdown of the monorepo layout, tech stack decisions, database schema, API design, authentication flow, and testing strategy.\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for the full release history.\n\n## Load Testing\n\nA [k6](https://k6.io) script is included to benchmark API latency under load.\n\n### Run the benchmark\n\nMake sure the API server is running:\n\n```bash\nk6 run apps/api/k6/latency.js\n```\n\nTarget a different host:\n\n```bash\nk6 run -e BASE_URL=http://your-host:3000 apps/api/k6/latency.js\n```\n\n### Scenario details\n\n- Ramps up to **50 virtual users** over 10 seconds\n- Sustains 50 virtual users for 20 seconds, then ramps down over 10 seconds\n- Each iteration creates a short URL, peeks it, and follows redirect\n- Threshold: p95 response time under **200ms**\n\n## License\n\n[MIT](LICENSE) — free to use, modify, and distribute. Attribution appreciated.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarvalhocaio%2Flink-arch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcarvalhocaio%2Flink-arch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarvalhocaio%2Flink-arch/lists"}