Read-later on your own ATProto repo. Saved state lives in link.latr.saved.item and link.latr.saved.external — no Stygian backend required for core functionality.
Next.js (latr.link) ── ATProto OAuth ──► Your PDS
XRPC link.latr.saved.item
link.latr.saved.external
latr-link/
apps/
web/ # Next.js web client (Bun)
latrkit-dev/ # LatrKit developer console (Bun)
packages/
latr-web-client/ # shared save/gateway client (Bun)
services/
latr-gateway/ # Swift/Hummingbird gateway (LatrKit via GitHub SwiftPM)
docs/
architecture/
| Tool | Version |
|---|---|
| Bun | ≥ 1.2 |
bun install
cd apps/web
cp .env.example .env.local
bun run devWith next dev or next start, opening http://127.0.0.1:3000 or http://localhost:3000 uses loopback OAuth automatically (no fetch to latr.link for client metadata). You do not need NODE_ENV=development for that. Optional apps/web/.env.local from .env.example tweaks timeouts and redirects.
Loopback OAuth must use a client_id that includes your /callback path and repo scopes. apps/web/.env.local should set NEXT_PUBLIC_APP_ENV=local (already in .env.example).
Production: set NEXT_PUBLIC_APP_ENV=prod on the host—if NEXT_PUBLIC_APP_ENV is unset at build/runtime, it defaults to local, which shows LOCAL-only UI on the live site. See apps/web/.env.example for prod / local / dev behavior.
Prefer http://127.0.0.1:3000 in the browser so the redirect URI matches ATProto loopback rules (see @atproto/oauth-client-browser README — the library may rewrite localhost to loopback IP).
Optional environment variables (see apps/web/.env.example):
NEXT_PUBLIC_LOCAL_REDIRECT_URI— if your dev URL is not the defaulthttp://127.0.0.1:<port>/callback.NEXT_PUBLIC_LOCAL_OAUTH_CLIENT_ID— full custom loopbackclient_idURL (advanced override).NEXT_PUBLIC_AUTH_RESTORE_TIMEOUT_MS— cap OAuth/IndexedDB restore wait in ms (default 8000) so the UI cannot stay on “Loading…” forever in embedded or broken browsers.
If the console shows WebSocket connection to .../_next/webpack-hmr failures, hot reload may not work in that environment; the app should still load. Use an external browser if the page stays blank after refresh.
| Script | Description |
|---|---|
bun run dev |
Turbo dev (web app) |
bun run build |
Production build |
bun run lint |
ESLint |
bun run typecheck |
TypeScript |
bun run test |
Unit tests (workspace) |
See docs/architecture/overview.md.
Deployment and database cutover procedures live in docs/deployment/railway.md.
Canonical link.latr.* schemas live in Stygian-Tech/latr-packages (packages/lexicons/). Legacy com.latr.* repo rows are migrated automatically by the gateway on list.