open-git
open-git is a GitHub-inspired code hosting app with stronger AI workflows, Better Auth for authentication, and a coss/Base UI foundation.
Apps and Packages
apps/web- Next.js App Router application.packages/ui- shared coss/Base UI components and global styles.packages/code-storage- isomorphic-git + S3 SDK package.
Authentication (Better Auth)
The app is wired for Better Auth with:
apps/web/lib/auth.ts- server auth instance (email/password, Resend emails).apps/web/lib/auth-client.ts- React client (useSession,signIn, ...).apps/web/app/api/auth/[...all]/route.ts- auth API route handler.apps/web/db/auth-schema.ts- Drizzle tables (auth_users,auth_sessions, ...).apps/web/app/sign-in,app/sign-up,app/forgot-password,app/reset-password- auth pages.apps/web/.env.example- required environment variables.
Copy apps/web/.env.example to apps/web/.env.local for local development.
Sign-up is email/password only; GitHub is available as a link-only connected
account for repository imports (set GITHUB_CLIENT_ID/GITHUB_CLIENT_SECRET).
Password reset and verification emails are sent through Resend
(RESEND_API_KEY); without a key they are logged to the console in dev.
DATABASE_URL=postgresql://opengit:opengit@localhost:54329/opengit
CODE_STORAGE_BUCKET=opengit-code-storage
CODE_STORAGE_REGION=us-east-1
CODE_STORAGE_S3_ENDPOINT=http://localhost:9000
CODE_STORAGE_ACCESS_KEY_ID=opengit
CODE_STORAGE_SECRET_ACCESS_KEY=opengit_password
GIT_REMOTE_BASE_URL=http://localhost:4321
GIT_GATEWAY_PORT=4321
GIT_GATEWAY_CACHE_ROOT=.git-gateway-cache
OPEN_GIT_INTERNAL_AUTH_URL=http://localhost:3001/api/internal/repository-authorizations
OPEN_GIT_INTERNAL_AUTH_SECRET=replace-with-a-random-secret
Start the web app:
pnpm dev
Seed local users, orgs, memberships, repository permissions, repositories, indexing jobs, and sample issues:
pnpm --filter web seed:local-dev
To wipe local app data first and rebuild the full fixture set:
pnpm --filter web reset:local-dev
Default login:
dev@open-git.local / password
Production deployments configure BETTER_AUTH_SECRET, RESEND_API_KEY, and
EMAIL_FROM; see deploy/.env.example.
Local Infrastructure
Better Auth owns authentication and session identity (stored in the same Postgres database). open-git owns product data that needs app-level invariants, starting with unique usernames.
The local development stack uses Postgres and MinIO:
compose.yaml- local Postgres and S3-compatible MinIO for OrbStack/Docker.apps/web/db/schema.ts- schema definitions.apps/web/db/index.ts- shared Drizzle client.apps/web/db/user-profiles.ts- auth user to app profile helper.apps/web/drizzle.config.ts- Drizzle migration config.packages/code-storage- SDK that stores bare Git repositories in S3.
user_profiles.stack_user_id is unique and maps to the Better Auth user id
(ids from the old Hexclave setup were preserved during the migration).
user_profiles.username is also unique, but nullable until the onboarding
flow lets a signed-in user reserve a username.
The onboarding flow lives at apps/web/app/onboarding. It validates usernames
on the server and writes the unique username to Postgres.
Start all local infrastructure, then generate and apply migrations from the web app package:
pnpm infra:up
pnpm --filter web db:generate
pnpm --filter web db:migrate
To start over from an empty local Postgres/MinIO state, stop the local
containers and delete their Docker volumes, then bring infra back up, migrate,
and reseed. For app-data-only resets, prefer reset:local-dev; it preserves
Drizzle migration history and refuses non-local environments.
docker compose down -v
pnpm infra:up
pnpm --filter web db:migrate
pnpm --filter web reset:local-dev
Local Postgres runs on localhost:54329 with database, username, and password
all set to opengit.
Local MinIO exposes the S3 API on localhost:9000 and the browser console on
http://localhost:9001. The local bucket is created automatically as
opengit-code-storage; the console login is opengit /
opengit_password.
UI work: Docker infra + Next.js only (hot reload)
For day-to-day UI and app behavior, run Postgres and MinIO in Docker, then run
only the web app so Next loads apps/web/.env.local and Turbopack hot-reloads.
pnpm infra:up
pnpm --filter web db:migrate # after schema changes: db:generate then migrate
pnpm dev
Open http://localhost:3001. Root pnpm dev starts only the web app. Use
pnpm dev:all only when you intend to start every package: the CLI runner
expects ~/.opengit/runner.json, and git-worker / managed-runner need
their own env and are not required for basic browsing and repository CRUD in
the UI.
Repository pages read from a Postgres index (branches, file tree, README HTML). Creating or forking a repo indexes synchronously in the web app. After git push through the gateway, run the indexing worker so the UI catches up:
pnpm --filter web indexing-worker
To clone or push over Git from your machine, run the gateway in a second
terminal (it uses the same env pattern as production; point DATABASE_URL and
S3 variables at the same Docker services as in .env.local):
pnpm --filter git-gateway dev
Git HTTP Gateway
The Git gateway exposes normal HTTPS-style Git remotes backed by the same S3 repository storage:
pnpm --filter git-gateway dev
git clone http://localhost:4321/<username>/<repository>.git
Public repositories can be cloned without credentials. Private clones and pushes
use HTTP Basic auth with your username and a Git token generated at
/settings/developer.
Adding components
To add coss components, run the registry command against the shared UI package:
pnpm dlx shadcn@latest add @coss/button -c packages/ui
This will place the shared components in the packages/ui/src/components directory.
Using components
To use the components in your app, import them from the ui package.
import { Button } from "@workspace/ui/components/button";