A lightweight, self-hosted Git platform — your own GitHub, built from scratch.
Tip
SetScript is a perfect foundation for building your own Git hosting platform. Fork it, extend it, and make it yours.
SetScript is an open-source, self-hosted Git platform written in Go (backend) and TypeScript / Next.js (frontend). It implements the Git Smart HTTP protocol natively, giving you real git clone, git push, and git pull over HTTP — no third-party Git server required.
Think of it as the lean, hackable alternative to GitHub, GitLab, or Gitea — built from first principles, easy to read, and easy to extend.
- Full Git Smart HTTP — clone, push, and pull repositories over HTTP using the standard Git protocol
- Repository management — create, browse, and delete public or private repositories
- File browser — navigate directory trees and view file contents at any branch or commit
- Commit history — paginated commit log with full diff viewer per commit
- Branch support — list and switch between branches across the entire UI
- README rendering — automatic Markdown rendering with GitHub Flavored Markdown support
- Star system — star repositories and track stargazers
- User profiles — public profile pages listing a user's repositories
- JWT authentication — stateless auth with 24-hour tokens, bcrypt password hashing
- Docker ready — multi-stage Dockerfile and
docker-compose.ymlincluded
| Layer | Technology |
|---|---|
| Backend | Go, Chi router, go-git |
| Frontend | Next.js 16, React 19, Tailwind CSS v4 |
| Database | PostgreSQL 16 (pgx driver) |
| Auth | JWT (HS256) + bcrypt |
| Git Protocol | Git Smart HTTP (upload-pack / receive-pack) |
| Containerization | Docker, Docker Compose |
- Go 1.21+
- Node.js 20+
- Docker & Docker Compose (for PostgreSQL)
git clone https://github.com/parsherr/setscript-v3.git
cd setscript-v3cd backend
make db-upcp .env.example .envEdit .env:
PORT=3000
DATABASE_URL=postgres://setscript:setscript@localhost:5432/setscript?sslmode=disable
JWT_SECRET=change-me-to-a-random-64-char-string
STORAGE_PATH=./data/repos
CORS_ORIGIN=http://localhost:3001cd ../frontend
cp .env.local.example .env.localNEXT_PUBLIC_API_URL=http://localhost:3000From the backend/ directory:
make devThis starts both the Go backend (:3000) and the Next.js frontend (:3001) concurrently.
Open http://localhost:3001 in your browser.
Build and run the backend as a container:
cd backend
docker build -t setscript .
docker-compose up -dThe backend exposes port 3000. Point your reverse proxy (nginx, Caddy, etc.) at it and serve the Next.js frontend separately or export it as a static build.
setscript-v3/
├── backend/
│ ├── cmd/server/ # Entry point — wires everything together
│ ├── internal/
│ │ ├── config/ # Env-based configuration
│ │ ├── database/ # PostgreSQL connection pool + migrations
│ │ ├── gitops/ # Git Smart HTTP protocol & git operations
│ │ ├── handler/ # HTTP handlers (thin layer over services)
│ │ ├── middleware/ # JWT auth, CORS, logging, panic recovery
│ │ ├── models/ # Request/response structs
│ │ ├── repository/ # Data access layer (SQL queries)
│ │ ├── router/ # Route definitions
│ │ ├── service/ # Business logic
│ │ └── util/ # JWT helpers, validation, response writers
│ ├── migrations/ # SQL migration files
│ └── data/repos/ # Bare Git repository storage
│
└── frontend/
└── src/
├── app/ # Next.js App Router pages
├── components/ # Reusable UI components
├── contexts/ # AuthContext (JWT + localStorage)
├── lib/api/ # Typed API client modules
└── types/ # Shared TypeScript interfaces
SetScript implements the Git Smart HTTP protocol directly in Go. When you run git clone http://localhost:3000/alice/my-repo.git:
git clone http://localhost:3000/alice/my-repo.git
↓
GET /alice/my-repo.git/info/refs?service=git-upload-pack
↓ Backend advertises available refs
POST /alice/my-repo.git/git-upload-pack
↓ Backend streams a packfile to the client
Repository cloned successfully
Push follows the same pattern via git-receive-pack. No shell exec, no git binary on the server — everything runs through the go-git library.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/auth/register |
Register a new user |
POST |
/api/auth/login |
Login and receive a JWT |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/users/:username |
Get user profile |
GET |
/api/users/:username/repos |
List a user's repositories |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/repos |
Required | Create a repository |
GET |
/api/repos/:owner/:repo |
Optional | Get repository details |
DELETE |
/api/repos/:owner/:repo |
Required | Delete a repository |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/repos/:owner/:repo/tree/:ref/*path |
Browse directory tree |
GET |
/api/repos/:owner/:repo/blob/:ref/*path |
View file contents |
GET |
/api/repos/:owner/:repo/raw/:ref/*path |
Download raw file |
GET |
/api/repos/:owner/:repo/commits/:ref |
Paginated commit log |
GET |
/api/repos/:owner/:repo/commits/:ref/sha/:sha |
Single commit with diff |
GET |
/api/repos/:owner/:repo/branches |
List branches |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
PUT |
/api/repos/:owner/:repo/star |
Required | Star a repository |
DELETE |
/api/repos/:owner/:repo/star |
Required | Unstar a repository |
GET |
/api/repos/:owner/:repo/star |
Optional | Check star status |
GET |
/api/repos/:owner/:repo/stargazers |
— | Get star count |
| Method | Endpoint | Description |
|---|---|---|
GET |
/:owner/:repo.git/info/refs |
Ref advertisement |
POST |
/:owner/:repo.git/git-upload-pack |
Clone / fetch |
POST |
/:owner/:repo.git/git-receive-pack |
Push |
SetScript uses four core tables:
users -- accounts, profile fields, bcrypt password hash
repositories -- repo metadata, owner FK, visibility flag
stars -- user_id + repo_id composite PK
ssh_keys -- public key storage (scaffolded, ready to extend)Migrations run automatically on server start via the built-in migration runner.
| Field | Rule |
|---|---|
| Username | 1–39 chars, alphanumeric + hyphens |
| Valid format, max 255 chars | |
| Password | 8–128 chars |
| Repository name | 1–100 chars, lowercase, alphanumeric + hyphens |
From the backend/ directory:
make run # Run the server
make build # Compile to ./bin/setscript
make dev # Run backend + frontend concurrently
make test # Run test suite
make db-up # Start PostgreSQL via Docker Compose
make db-down # Stop PostgreSQL
make migrate # Run migrations only
make clean # Remove build artifacts- SSH key authentication for git push/pull
- Issues and pull request system
- Organization / team support
- Webhook delivery on push events
- Rate limiting and abuse protection
- Email notifications
- Repository forking
- Release / tag management
Contributions are welcome. To get started:
- Fork this repository
- Create a branch:
git checkout -b feat/my-feature - Make your changes and commit:
git commit -m 'feat: add my feature' - Push to your fork:
git push origin feat/my-feature - Open a pull request
Please keep pull requests focused and atomic. If you're planning a large change, open an issue first to discuss the approach.
SetScript is open-source software licensed under the MIT License.
Built with Go + Next.js · Inspired by GitHub, GitLab, and Gitea