{"id":51640805,"url":"https://github.com/tamnd/githome","last_synced_at":"2026-07-13T19:03:05.901Z","repository":{"id":362516416,"uuid":"1259225964","full_name":"tamnd/githome","owner":"tamnd","description":"A self-hosted, GitHub-compatible software forge written in Go. REST v3, GraphQL v4, and the gh CLI, byte for byte.","archived":false,"fork":false,"pushed_at":"2026-06-29T13:11:13.000Z","size":3438,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-29T15:11:38.883Z","etag":null,"topics":["code-review","developer-tools","forge","gh-cli","git","git-server","gitea-alternative","github-alternative","github-api","github-compatible","go","golang","graphql","issue-tracker","pull-requests","rest-api","self-hosted","single-binary","version-control","webhooks"],"latest_commit_sha":null,"homepage":"https://githome.tamnd.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tamnd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-06-04T09:56:09.000Z","updated_at":"2026-06-29T13:11:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tamnd/githome","commit_stats":null,"previous_names":["tamnd/githome"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/tamnd/githome","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamnd%2Fgithome","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamnd%2Fgithome/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamnd%2Fgithome/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamnd%2Fgithome/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tamnd","download_url":"https://codeload.github.com/tamnd/githome/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tamnd%2Fgithome/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35432821,"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-07-13T02:00:06.543Z","response_time":119,"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":["code-review","developer-tools","forge","gh-cli","git","git-server","gitea-alternative","github-alternative","github-api","github-compatible","go","golang","graphql","issue-tracker","pull-requests","rest-api","self-hosted","single-binary","version-control","webhooks"],"created_at":"2026-07-13T19:02:59.919Z","updated_at":"2026-07-13T19:03:05.887Z","avatar_url":"https://github.com/tamnd.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Githome\n\nGithome is a self-hosted software forge that speaks GitHub. The goal is narrow and uncompromising: an unmodified `gh`, an unmodified `git`, and any client that talks to the GitHub REST or GraphQL API should work against a Githome server the same way they work against github.com, byte for byte where it matters.\n\nThat means the compatibility target is not \"GitHub-like\". It is GitHub:\n\n- **REST API v3** under `/api/v3`, with the same JSON shapes, the same error envelopes, the same headers (`Link` pagination, `ETag`, the rate-limit family, `X-GitHub-Request-Id`, `X-GitHub-Api-Version`).\n- **GraphQL API v4** under `/api/graphql`, with a schema that matches field for field, Relay-style connections, and the `node`/`databaseId`/`id` triple.\n- **The `gh` CLI**, unmodified, pointed at a Githome host through `GH_HOST`. If a flow works on github.com it works here, including `--json` field selection and `--paginate`.\n- **Git transport** over smart-HTTP, so `git clone` and `git push` go straight to the server.\n- **A built-in web UI**, served from the same binary and on by default: repo and code browsing, Markdown with syntax highlighting, issues, pull requests with the diff, inline code review, search, profiles, and settings. It is a reimplemented Primer look, server-rendered, and the write paths work with JavaScript disabled.\n\n## Status\n\nUsable today, and honest about the edges. The compatibility surface is built and released: four tagged versions are out, and one tag push produces the prebuilt binaries, the Linux packages, and the container image attached to each release (see [Install](#install)).\n\n| Version | What it added |\n| --- | --- |\n| `v0.1.0` | The first complete forge: auth, git read and push, issues, pull requests, code review, webhooks, events, search, conditional requests, the full REST and GraphQL surface |\n| `v0.1.1` | A performance pass: batch loaders instead of N+1, keyset pagination, FTS-backed search, object caches, GraphQL dataloaders |\n| `v0.1.2` | The release pipeline: archives, deb/rpm/apk, a multi-arch container image, and the language-agnostic package managers |\n| `v0.1.3` | The built-in web UI (repo and code browsing, diffs, inline review, profiles, settings, notifications), a conformance suite wired into CI, the REST and GraphQL compatibility ladders, h2c serving, and a green Postgres test leg |\n\nWhat works, end to end:\n\n- **Authentication.** Classic PATs with a prefix and checksum, the OAuth device and web flows, scopes on every response header, only the token hash stored.\n- **Repositories and git.** `gh repo` operations, `git clone`, `git fetch`, and `git push` over smart-HTTP, with a post-receive sync that keeps the database consistent with what git wrote.\n- **Issues, pull requests, and code review.** The full lifecycle over REST and GraphQL, async mergeable state, squash/merge/rebase, inline review threads, commit statuses, check runs, `reviewDecision`, and `statusCheckRollup`.\n- **Webhooks and the Events API**, with `X-Hub-Signature-256` delivery, an SSRF guard, and at-least-once retry.\n- **Search, pagination, and conditional requests**, with FTS-backed search, RFC 5988 `Link` headers, and `ETag`/`If-None-Match` that returns 304 without spending rate limit.\n- **The web UI** described above.\n\nNot yet:\n\n- SSH git transport (the config is reserved, the server is not wired)\n- Organization accounts (everything is user-owned for now)\n- At-rest encryption of webhook secrets\n- GitHub Actions runner compatibility (in progress in the separate `tamnd/githome-action` project, not yet served by this binary)\n\nThe definition of done is mechanical, not a claim. Every endpoint has a recorded fixture and a contract test; real `gh` and real `git` drive the server in CI; a JSON differ compares responses against recorded github.com output field for field; and the suite runs against both SQLite and Postgres. The `githome-conform` tool certifies a running instance against the compatibility matrix as a black-box client and exits non-zero on any drift, so it can gate a release.\n\n## Design in one screen\n\n- One Go binary, `githome`, that serves the REST and GraphQL APIs, the git smart-HTTP transport, and the web UI. Two helpers ship beside it: `githome-migrate` runs the schema migrations, and `githome-conform` certifies a running instance against the compatibility matrix.\n- Postgres is the primary datastore; SQLite (pure Go, no cgo) is supported for small and single-node deployments. The same migrations run on both, and the server applies them on startup.\n- Git access is hybrid: go-git for cheap reads, the `git` binary for transport, merge, and diff.\n- One rule keeps the API surfaces from drifting apart: the REST, GraphQL, and web layers never touch the store or git directly. They all go through the domain layer for data and a presenter layer for rendering, so no surface can diverge from another or from GitHub.\n\nThere are no Go `internal/` directories in this project on purpose; boundaries are enforced by the single-writer domain layer and by lint, not by the package system.\n\n## Install\n\nTagged releases ship as static binaries for Linux, macOS, Windows and the BSDs, as Linux packages (deb, rpm, apk), and as a multi-arch container image. The paths that work today:\n\n```sh\ndocker pull ghcr.io/tamnd/githome:latest                # container\ngo install github.com/tamnd/githome/cmd/githome@latest  # from source\n```\n\nEvery release also attaches prebuilt archives and `deb`/`rpm`/`apk` packages you can download and install directly. The pipeline additionally builds Homebrew, Scoop, winget, AUR and Nix entries; those go live once their taps are created and their tokens are set, which [INSTALL.md](INSTALL.md) walks through alongside every install method and the server configuration.\n\n## Run\n\nThe server reads its configuration from the environment and applies migrations on startup, so a single-node SQLite instance needs nothing but a few variables:\n\n```sh\nexport GITHOME_DATABASE_URL=\"sqlite://githome.db\"\nexport GITHOME_DATA_DIR=\"./data\"\nexport GITHOME_HTML_BASE_URL=\"http://localhost:3000\"\nexport GITHOME_SESSION_KEY=\"$(openssl rand -hex 32)\"   # at least 32 bytes\nexport GITHOME_TOKEN_PEPPER=\"$(openssl rand -hex 32)\"  # at least 16 bytes\ngithome\n```\n\nIt listens on `:3000` by default and serves the web UI, the REST API under `/api/v3`, GraphQL under `/api/graphql`, and the git smart-HTTP transport. Point `gh` and `git` at it:\n\n```sh\nexport GH_HOST=localhost:3000\ngh auth login --hostname localhost:3000\ngh repo create myrepo --private\ngit clone http://localhost:3000/\u003cyou\u003e/myrepo.git\n```\n\nUse a `postgres://` DSN for multi-node or production deployments. Every variable, including the optional ones, is documented in [INSTALL.md](INSTALL.md#configuration) and in the packaged `githome.env`.\n\n## Build\n\nRequires Go 1.26 or newer and a `git` binary on `PATH`.\n\n```sh\nmake build          # build ./bin/githome and ./bin/githome-migrate\nmake test           # run the test suite (SQLite)\nmake test-postgres  # run it against a local Postgres (make pg-up first)\nmake lint           # golangci-lint v2\nmake gates          # the cross-cutting CI checks (no internal/, no leaked hosts)\n```\n\n## License\n\nApache License 2.0. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftamnd%2Fgithome","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftamnd%2Fgithome","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftamnd%2Fgithome/lists"}