Code collaboration for the small web

gitxt is a purely decentralised Git forge. No federation protocol. No central servers. No accounts on other people's machines. Just git, HTTP, and plain text files.

Get the source Read the spec

$ curl https://gitxt.mills.io/~prologic/gitxt/forge.txt   # try it — gitxt hosts itself

# nick = gitxt
# type = forge
# clone = https://gitxt.mills.io/~prologic/gitxt.git

2026-09-01T10:00:00Z	[issue] Crash on empty input
2026-09-01T12:30:00Z	(#a3f9k2c) [patch] fix crash repo=https://bob.example/~bob/myproj.git ref=fix-crash
2026-09-01T13:00:00Z	(#a3f9k2c) [merge] merged into main commit=deadbee

ðŸ“Ą Feeds, not federation

Every repository publishes a forge feed — an append-only, plain-text, twtxt-compatible file carrying its issues, patches and reviews. Other instances simply follow it over HTTP. Inspired by Twtxt & Yarn.social.

🔀 Patches are pointers

A patch entry names a clone URL and a branch on the contributor’s own instance. The maintainer’s instance fetches it with ordinary git fetch, renders the diff like a pull request, and merges with one click.

ðŸĄ Fully independent instances

Fork by pasting a feed URL: your instance clones the repo and follows the upstream feed. You file issues and push fixes on your own forge — the upstream maintainer reads them from theirs.

🔑 Your SSH key is your login

Web login by signing a challenge with ssh-keygen -Y sign. Pushes are gated by a bearer token. No passwords, no OAuth, no third parties.

📖 Readable with curl

The whole collaboration history of a project is one text file. Any twtxt client can follow a forge feed; humans can read it raw.

ðŸŠķ One small binary

Go, SQLite (a rebuildable cache — the feeds are the source of truth), and the real git underneath. Nothing else to run.

How it works

  1. Alice hosts myproj on her instance; its feed lives at https://alice.example/~alice/myproj/forge.txt.
  2. Bob forks it onto his instance by pasting that feed URL.
  3. Bob files an issue and pushes a fix branch to his own fork, then publishes a [patch] entry pointing at his clone URL + branch.
  4. Alice’s instance — following Bob’s feed, nudged by an optional ping — shows the issue and renders the patch: commits, diff, merge button.
  5. Alice merges (a real, local git merge) and her feed records [merge]. Bob’s instance picks it up on its next poll.

If every optional ping in the world is lost, nothing breaks: plain HTTP polling delivers everything, eventually.

Quick start

Requires Go â‰Ĩ 1.24 and git.

go install gitxt.dev/cmd/gitxt@latest

gitxt init -u alice -b https://alice.example --key ~/.ssh/id_ed25519.pub
gitxt serve

Then create a repository, push to it, and hand the world one URL: your forge feed.

Learn more