Ripgit is one of the more interesting projects in the growing Cloudflare application ecosystem.

Most Git self-hosting discussions start with a VPS and end with something like Forgejo, Gitea, GitLab CE, or a bare Git server behind SSH.

Ripgit takes a different path: it stores Git repositories inside Cloudflare Durable Objects, runs the application as a Cloudflare Worker, and exposes a standard Git-over-HTTP remote.

That makes it self-hostable, but not in the old Docker-on-a-server sense.

What is Ripgit?

Ripgit is:

“A self-hostable git remote backed by Cloudflare Durable Objects.”

The core idea is simple:

one repository = one Durable Object

Each repository gets isolated Durable Object state with SQLite storage. Ripgit then implements enough of the Git smart HTTP protocol for normal workflows such as:

git remote add origin https://your-worker.workers.dev/username/myproject
git push origin main
git clone https://your-worker.workers.dev/username/myproject

It is not just an object bucket. The repo includes a web UI, code browser, commit pages, diffs, full-text search, raw file serving, issues, pull requests, and JSON/text APIs.

Can Ripgit Be Self-Hosted?

Yes, but the word self-hosted needs precision here.

Ripgit can be deployed into your own Cloudflare account. You control the Worker, Durable Object namespace, KV namespaces, routes, secrets, and optional auth worker.

That is self-hosting in the Cloudflare-native/serverless sense.

It is not self-hosting in the Forgejo sense, where you run a container or binary on a homelab machine and back up a local volume.

If you want that distinction in more detail, this post pairs well with the earlier Cloudflare Workers, D1, KV, and R2 serverless stack overview.

Tech Overview

Ripgit’s main worker is written in Rust using workers-rs.

The interesting components are:

Component What it does
Cloudflare Worker Routes browser, API, and Git HTTP requests
Durable Objects One stateful object per repository
Durable Object SQLite Stores refs, commits, trees, blobs, issues, PRs, search indexes
Cloudflare KV Stores repository registry entries for owner profile pages
Optional auth Worker Handles GitHub OAuth, browser sessions, and long-lived Git tokens
Service Binding Lets the auth worker call the Ripgit worker privately
SQLite FTS5 Powers code and commit-message search
xpatch + zlib Stores changed blob versions efficiently

The local schema includes tables for Git refs, commits, commit parents, tree entries, blob groups, blob chunks, raw objects, config, issues, issue comments, and FTS5 indexes.

That explains the main tradeoff. Ripgit is compact because it uses Cloudflare’s platform primitives directly. It is also platform-specific for the same reason.

What You Get

Ripgit supports standard Git-over-HTTP paths for pushing, cloning, and fetching.

It also exposes a useful set of web and API routes:

/:owner/
/:owner/:repo/
/:owner/:repo/commits
/:owner/:repo/commit/:sha
/:owner/:repo/tree/:ref/*path
/:owner/:repo/blob/:ref/*path
/:owner/:repo/raw/:ref/*path
/:owner/:repo/search-ui
/:owner/:repo/issues
/:owner/:repo/pulls
/:owner/:repo/settings

For programmatic use, the JSON API includes refs, logs, commits, trees, blobs, files, search, diffs, comparisons, and stats:

curl https://your-worker.example/alice/project/refs
curl "https://your-worker.example/alice/project/log?ref=main&limit=50"
curl "https://your-worker.example/alice/project/search?q=TODO"
curl https://your-worker.example/alice/project/stats

Many browser pages also support markdown or plain-text negotiation:

curl -H "Accept: text/markdown" https://your-worker.example/alice/project/
curl -H "Accept: text/plain" https://your-worker.example/alice/project/settings
curl "https://your-worker.example/alice/project/?format=md"

That agent-friendly design is one of Ripgit’s strongest differentiators. A coding agent, shell script, or terminal workflow can inspect a repository without scraping HTML.

Deployment Shape

The root wrangler.toml defines:

name = "ripgit"
main = "build/index.js"
compatibility_date = "2026-03-18"

[[kv_namespaces]]
binding = "REGISTRY"

[durable_objects]
bindings = [
  { name = "REPOSITORY", class_name = "Repository" }
]

[[migrations]]
tag = "v1"
new_sqlite_classes = ["Repository"]

The basic deploy flow is:

git clone https://github.com/deathbyknowledge/ripgit
cd ripgit

wrangler kv namespace create REGISTRY
# paste the generated namespace ID into wrangler.toml

wrangler deploy

For a real deployment, you should put the GitHub OAuth example worker in front of it.

cd examples/github-oauth
npm install

wrangler kv namespace create OAUTH_KV
wrangler kv namespace create OAUTH_KV --preview

wrangler secret put GITHUB_CLIENT_SECRET
wrangler secret put SESSION_SECRET

wrangler deploy

The auth worker needs:

  • GITHUB_CLIENT_ID
  • GITHUB_CLIENT_SECRET
  • SESSION_SECRET
  • OAUTH_KV
  • a RIPGIT Service Binding pointing to the main Ripgit Worker

Important: the README warns that if you deploy the main Ripgit worker without an auth worker in front of it, repositories are publicly readable and writable by anyone who knows the URL.

Field Note: Local Trial

I cloned the repository locally at commit 21dba30423a38f0ecb5a9e2ce79bbfc4f2d36669.

This machine had:

Node.js v18.19.1
npm 9.2.0
rustc 1.75.0
cargo 1.75.0

Root npm install completed, and the OAuth worker TypeScript check passed:

cd examples/github-oauth
npm install
npm run typecheck

The main worker did not build on this host because the available toolchain is too old:

  • cargo check failed because Cargo.lock uses lockfile version 4.
  • npm test failed while installing/building worker-build, because current crates require newer Cargo support.
  • npx wrangler --version failed because current Wrangler requires Node.js 20+, while this host has Node.js 18.

So the practical prerequisite is: use Node.js 20+ and a current Rust/Cargo toolchain before trying local Miniflare tests or deployment.

Ripgit vs Forgejo

Ripgit and Forgejo both host Git repositories, but they are not trying to be the same product.

Question Ripgit Forgejo
How do I run it? Cloudflare Workers, Durable Objects, KV Docker, binary, VPS, homelab, Kubernetes
Is there a normal Docker Compose setup? No Yes
Where is repo data stored? Durable Object SQLite Local disk plus SQLite/Postgres/MySQL
Git over SSH? No clear SSH support; Git-over-HTTP is the target Yes
Built-in user/admin system? Minimal; use an upstream auth worker Yes
Issues and pull requests? Yes, lightweight implementation Yes, mature forge workflow
CI/CD? Not built in Forgejo Actions
Package registry? Not built in Yes
Best use case Cloudflare-native Git remote, agent-friendly repo publishing, small edge-hosted Git service Full self-hosted GitHub/Gitea alternative

Use Forgejo if you want a complete self-hosted software forge: users, orgs, SSH, protected workflows, package registry, webhooks, CI runners, admin settings, backups, and conventional server ownership.

Use Ripgit if the interesting part is the architecture itself: Git hosting without a VPS, per-repository Durable Objects, low server maintenance, and API/text-first repository access.

When I Would Pick Ripgit

Ripgit makes sense when:

  • you are already comfortable with Cloudflare Workers;
  • you want to experiment with Git repositories as edge-native objects;
  • your repositories are small or moderate;
  • you want HTTP APIs and markdown/plain-text views for scripts or agents;
  • you do not need a full organization-scale forge;
  • Cloudflare platform lock-in is acceptable.

I would not use it as my main Forgejo replacement yet for a team that depends on mature Git forge features every day.

I would use it as a fascinating Cloudflare-native Git remote, especially for agent-facing repositories, public code mirrors, small project publishing, and experiments around serverless developer infrastructure.

FAQ