shyim / composer-go-proxy
Downloads Composer package dists via proxy.golang.org (Go module proxy) instead of the GitHub API for better stability and no rate limits
Package info
github.com/shyim/composer-go-proxy
Type:composer-plugin
pkg:composer/shyim/composer-go-proxy
Requires
- php: >=7.4
- composer-plugin-api: ^2.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A Composer plugin that downloads package dists through proxy.golang.org — the Go module proxy — instead of the GitHub API.
Why
By default, Composer downloads package archives from api.github.com, which is
- rate limited (60 req/h unauthenticated, CI pipelines regularly hit this),
- an extra moving part that can be slow or down,
- not immutable — force-pushed or deleted tags change or lose content.
The Go module proxy already fetches every public git repository at every vX.Y.Z tag and caches the resulting zip forever, served by Google's CDN. This plugin makes Composer use that infrastructure: faster, stable, no rate limits, no tokens.
How it works
- For every package with a GitHub/GitLab/Bitbucket dist URL and a
v-prefixed semantic version, the plugin registers the Go module ziphttps://proxy.golang.org/<module>/@v/<version>.zipas a preferred dist mirror. - Packages with other tag schemes (e.g.
1.20.0withoutv) and dev versions are covered too: the plugin resolves the dist commit SHA to a Go pseudo-version via the proxy's.infoendpoint and serves that zip (the lookup result is cached in Composer's file cache). - Composer tries the Go proxy first. On any failure (unknown tag, private repo, proxy hiccup) it automatically falls back to the original dist URL — installs can never break because of the plugin.
- Go module zips nest all files below
<module>@<version>/, which Composer cannot extract correctly, so the plugin flattens that prefix after extraction. - Go module zips always contain the full repository tree, while GitHub zipballs honor
.gitattributesexport-ignorerules. The plugin reapplies those rules after extraction, so the installed files are identical to the original dist (no tests, CI configs or subsplit packages leaking intovendor/).
Repositories without a go.mod (virtually every PHP package) are served with a +incompatible suffix once their major version is ≥ 2 — the plugin registers both candidates and lets the fallback pick the right one.
Installation
composer global require shyim/composer-go-proxy
composer global config allow-plugins.shyim/composer-go-proxy true
That's it — every composer install / update in every project now uses the Go proxy when possible.
Supported hosts
Works out of the box for packages hosted on:
github.comgitlab.combitbucket.org
Self-hosted git servers (GitLab CE, Gitea, Forgejo, Codeberg, …) can be enabled additionally, as long as they are publicly reachable and serve go-import meta tags:
export COMPOSER_GO_PROXY_HOSTS="git.example.com,codeberg.org"
Configuration
| Env var | Description |
|---|---|
COMPOSER_GO_PROXY_HOSTS |
Comma-separated list of additional allowed git hosts |
COMPOSER_GO_PROXY_DISABLE |
Set to 1 to completely disable the plugin (debugging) |
Limitations
- Only public repositories — the Go proxy has no credentials. Private packages fall back to the original URL. Their paths are also never sent to the proxy unless their host is allowlisted via
COMPOSER_GO_PROXY_HOSTS. - Non-
v-prefixed tags and dev versions require one small.infolookup per package (cached afterwards) to resolve the commit to a pseudo-version.
License
MIT