# Forge — one CLI for every git forge

Third Nesbitt piece on the wiki. The pattern repeats: he notices a layer of open-source infrastructure where every ecosystem has independently implemented the same thing in incompatible ways, and he builds a normalization layer over the top. Libraries.io and [ecosyste.ms](https://ecosyste.ms) did this for package registries. git-pkgs did it for lockfiles. Forge does it for git hosts.

## The fragmentation

Every forge has its own CLI. `gh` for GitHub, `glab` for GitLab, `tea` for Gitea/Forgejo, various options for Bitbucket. They all do roughly the same things — open PRs, list issues, cut releases, manage secrets — and they all disagree about the syntax for doing them. Different subcommand trees, different flag conventions, different mental models of which API endpoints get their own command and which live under some generic `api` escape hatch.

The result is a usability tax that scales with the number of forges you touch. Someone who works across two of them pays it constantly; someone who only uses GitHub doesn't notice it exists.

## What Forge is

A single Go CLI and Go library that auto-detects the forge from the current git remote and issues the right API calls behind a consistent command surface:

```
forge repo view
forge issue list --state open
forge pr create --title "Fix bug" --head fix-branch
forge release list
```

Coverage is roughly the same set `gh` covers: repositories, issues, PRs, releases, branches, CI pipelines, labels, milestones, deploy keys, secrets, comments. Self-hosted instances are detected from the remote URL alongside the cloud-hosted ones.

Authentication reuses existing state — it reads `gh` and `glab` tokens from their usual locations, and also takes flags, environment variables, or a config file. So for someone who already has `gh auth login` done and a GitLab personal access token exported, Forge works out of the box.

## The library angle

The CLI is one half. The other half is an importable Go module that exposes the same consistent API — so a program calling Forge doesn't need per-provider conditionals, just a single interface with pluggable backends.

This is the more durable contribution. A CLI is a productivity tool for one person; a library is infrastructure for every subsequent tool that wants forge-agnosticism without rebuilding the abstraction.

## The AI-agent framing

The interesting forward-looking claim: most coding agents today hardcode GitHub's API. When the user's project lives on GitLab, or Gitea, or a self-hosted Forgejo, the agent either ignores the forge entirely or falls back to shelling out to `git` and losing access to PRs, issues, and CI. Nesbitt's framing is that an abstraction layer like Forge "makes the agent code simpler and the forge choice less of a lock-in decision."

Same move as [[alternative-frontend-pattern]] but in the other direction: instead of a frontend that can talk to only one backend's data shape, a client that can talk to many backends through one shape.

## Limitations

- Go-only for the library. If your agent framework is in TypeScript or Python you get the CLI but not the module.
- The set of supported forges is what it is — sourcehut, Codeberg-beyond-Forgejo, commercial systems like Bitbucket Data Center, etc. aren't covered.
- As with any normalization layer, the intersection of features across forges is smaller than any individual forge's native set. Forge gives you the common shape, not every forge's full capability.

## Relevance

For a developer juggling multiple forges (e.g. GitHub for work and a different host for personal projects), Forge is a plausible replacement for learning two or three CLIs. For agent builders, it's infrastructure worth tracking — the same way Libraries.io became load-bearing for supply-chain analysis after "can we just parse package.json" stopped scaling.

## Related

- [[nesbitt-io]] — blog entity; third ingested article
- [[features-to-steal-from-npmx]] — prior Nesbitt piece, also about alternative frontends over incumbent infrastructure
- [[git-magic-files]] — prior Nesbitt piece on what git itself tracks at the repo level
- [[alternative-frontend-pattern]] — adjacent concept, reverse direction
- [[toolbox/forge]] — the tool itself
