Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Open more actions menu

Repository files navigation

Typed Go client for pkg.go.dev

tag Go Version GoDoc Build Status Go report Contributors License

A typed Go client for the pkg.go.dev API (the "Go Pkgsite API", https://pkg.go.dev/v1beta): search packages and symbols, read documentation (whole package or a single symbol), list versions, importers, known vulnerabilities and a module's dependencies.

The public API lives at the module root (package pkggodev): context-first methods, functional options, clean typed results (no ogen codegen leakage) and auto-paginating iterators. It wraps an ogen-generated client kept under internal/api.

Optional response fields are typed as mo.Option[T] (e.g. pkg.Synopsis is mo.Option[string], module.Size is mo.Option[int64]): the type tells absent apart from a zero value, with no leaked codegen wrappers. Read them with .OrEmpty(), .Get(), .MustGet() or .IsAbsent(). Required fields stay plain (pkg.Path is a string). When marshalled back to JSON, absent options are omitted (omitzero).

Tip

Looking for a CLI or MCP instead of a Go library? Use samber/godig — the pkg.go.dev CLI powered by this client.

🚀 Install

go get github.com/samber/go-pkggodev-client

This library is v0 and follows SemVer. It is compatible with Go >= 1.25 (uses iter.Seq2).

💡 Quick start

import pkggodev "github.com/samber/go-pkggodev-client"

c, err := pkggodev.New(pkggodev.WithUserAgent("my-app/1.0"))
if err != nil {
	panic(err)
}

// Single object.
pkg, _ := c.Package(ctx, "github.com/samber/lo")
fmt.Println(pkg.Path, pkg.Synopsis.OrEmpty()) // required string + optional mo.Option[string]

// A single symbol's documentation (token-efficient, no full package blob).
sym, err := c.Symbol(ctx, "github.com/samber/lo", "Map", pkggodev.WithExamples())
if errors.Is(err, pkggodev.ErrSymbolNotFound) {
	// symbol does not exist in the package
}
fmt.Println(sym.Kind, sym.Signature) // "Function", "func Map[...](...) ..."
fmt.Println(sym.Synopsis.OrEmpty())  // first sentence of the doc

// One page.
page, _ := c.Versions(ctx, "github.com/samber/lo", pkggodev.WithLimit(10))
fmt.Println(page.Total, page.NextToken.OrEmpty())

// All results, auto-paginated.
for v, err := range c.AllVersions(ctx, "github.com/samber/lo") {
	if err != nil {
		break
	}
	fmt.Println(v.Version, v.CommitTime)
}

// A module's dependencies, parsed from the go.mod on the Go module proxy.
deps, _ := c.Dependencies(ctx, "github.com/samber/do/v2")
for _, d := range deps.Requires {
	fmt.Println(d.Path, d.Version.OrEmpty(), d.Indirect) // github.com/samber/go-type-to-string v1.8.0 false
}

// Module download size (Content-Length of the proxy zip), opt-in via WithSize.
m, _ := c.Module(ctx, "github.com/samber/do/v2", pkggodev.WithSize())
fmt.Println(m.GoVersion.OrEmpty(), m.Size.OrEmpty()) // "1.18" 65031 (bytes)

🧠 Spec

GoDoc: https://pkg.go.dev/github.com/samber/go-pkggodev-client

Client constructor

func New(opts ...ClientOption) (*Client, error)
  • WithBaseURL(url) — override the API base URL.
  • WithVulnBaseURL(url) — override the Go vulnerability database base URL used by Vulns (defaults to https://vuln.go.dev).
  • WithHTTPClient(*http.Client) — custom timeouts / transport.
  • WithUserAgent(string) — set the User-Agent header.
  • WithGoproxy(string) — override the module proxy list used by MajorVersions, Dependencies and Module/Versions with WithSize (same syntax as the GOPROXY env var; honored by default, defaulting to https://proxy.golang.org).

Methods

All take context.Context first and return clean, typed values:

Method Returns
Search(ctx, opts...) *Page[SearchResult]
Package(ctx, path, opts...) *Package
ImportedBy(ctx, path, opts...) *ImportedByResult
Packages(ctx, path, opts...) *PackagesResult
Module(ctx, path, opts...) *Module
Versions(ctx, path, opts...) *Page[ModuleVersion]
Symbols(ctx, path, opts...) *Page[SymbolInfo]
Symbol(ctx, path, symbol, opts...) *Symbol
Vulns(ctx, path, opts...) []Vulnerability
MajorVersions(ctx, modulePath, opts...) *Page[MajorVersion]
Dependencies(ctx, modulePath, opts...) *DependenciesResult

Symbols lists the package symbols as lightweight SymbolInfo values (name, kind, synopsis, parent). Symbol returns the full documentation of a single symbol (func, type, method, var or const) instead of the whole package doc blob — handy to keep token usage low. symbol is the exported identifier ("Map") or "Type.Method" ("Either.ForEach"); matching is case-sensitive. The doc is derived client-side from the package documentation (always fetched as Markdown, so WithDoc is ignored here) and the method returns ErrSymbolNotFound when the symbol is absent. Pass WithExamples to include runnable examples.

Vulnerabilities

Vulns is sourced directly from the Go vulnerability database in OSV format, so each Vulnerability carries far more than a summary: CVE/GHSA Aliases, affected version Ranges, the affected Packages and their Symbols, References, review status and the pkg.go.dev/vuln URL. path may be a module path (exact match) or a package path (matched to its owning module); standard-library imports such as crypto/x509 resolve to the stdlib pseudo-module.

The result is scoped to the queried module, so there is no single fixedVersion field: a module can be fixed across several disjoint intervals, so the fix lives per-interval in Ranges[].Fixed.

for _, v := range vulns {
    fmt.Println(v.ID, v.Aliases) // GO-2021-0113 [CVE-2021-38561 GHSA-ppp9-7jff-5vj2]
    for _, r := range v.Ranges {
        fmt.Printf("  introduced %s, fixed %s\n", r.Introduced.OrEmpty(), r.Fixed.OrEmpty())
    }
}

Pass WithVersion with a concrete semver to keep only the vulnerabilities actually affecting that version (read the covering fix from Ranges); WithLimit caps the result. The database is fetched whole rather than paginated, so Vulns returns a plain slice.

Major versions

In Go, major versions beyond v1 live as separate modules (path, path/v2, path/v3…) and can be non-contiguous (e.g. v1, v2, v4, v6). pkg.go.dev does not yet expose a MajorVersions endpoint (golang/go#76718), so MajorVersions derives the answer from the Go module proxy — honoring GOPROXY (see WithGoproxy). It lists the tagged versions of the base path (which yields v0, v1 and any +incompatible majors that share it) and probes path/vN for higher majors. gopkg.in/pkg.vN paths are supported too.

page, _ := c.MajorVersions(ctx, "github.com/samber/do")
for _, mv := range page.Items {
	fmt.Println(mv.Major, mv.ModulePath, mv.Version, mv.IsLatest)
	// v2 github.com/samber/do/v2 v2.0.0 true
	// v1 github.com/samber/do    v1.6.0 false
}

Each MajorVersion carries its own ModulePath, the Major ("v2"), the latest Version in that major, and IsLatest for the highest major. Results are sorted newest-major-first. The module proxy has no pagination cursor, so the result is a single page. WithExcludePseudo drops majors whose latest version is a pseudo-version (reflecting ExcludePseudo from the proposal); WithLimit caps the number of returned majors (the proposal's Max); WithFilter matches each major's module path. MajorVersions returns ErrProxyDisabled when GOPROXY is off/direct-only and ErrInvalidModulePath for an unparsable path.

Dependencies

pkg.go.dev does not expose a dependencies endpoint, so Dependencies reads and parses the module's go.mod straight from the Go module proxy (honoring GOPROXY, see WithGoproxy). It returns the require directives (each with its version and whether it is // indirect), plus any replace and exclude directives and the module's go directive.

deps, _ := c.Dependencies(ctx, "github.com/samber/do/v2")
fmt.Println(deps.Version, deps.GoVersion.OrEmpty()) // resolved version + go directive, e.g. "v2.0.0" "1.18"
for _, d := range deps.Requires {
	fmt.Println(d.Path, d.Version.OrEmpty(), d.Indirect)
}

WithVersion selects the version; when unset (or "latest") the proxy's latest version is used and Version reports the concrete version the go.mod was read at. Dependencies returns ErrProxyDisabled when GOPROXY is off/direct-only, ErrInvalidModulePath for an unparsable path, and ErrModuleNotFound when the module version is unknown to every proxy.

Module download size

Module always reports the go directive of the module's go.mod in Module.GoVersion (read from the already-returned go.mod contents, no extra request). Download sizes are opt-in via WithSize: a size is the Content-Length of the module zip on the Go module proxy, fetched with a HEAD request (the archive is never downloaded). It populates Module.Size (one extra request) and, on Versions / AllVersions, ModuleVersion.Size for each listed version (one concurrent request per version).

m, _ := c.Module(ctx, "github.com/samber/do/v2", pkggodev.WithSize())
fmt.Println(m.GoVersion.OrEmpty(), m.Size.OrEmpty()) // "1.18" 65031  (bytes)

// Size of every release, fetched concurrently.
for v, err := range c.AllVersions(ctx, "github.com/samber/do/v2", pkggodev.WithSize()) {
	if err != nil {
		break
	}
	fmt.Println(v.Version, v.Size.OrEmpty())
}

Module and Versions return ErrProxyDisabled when WithSize is set but GOPROXY is off/direct-only.

Call options

WithVersion, WithModule, WithLimit, WithToken, WithFilter, WithGOOS, WithGOARCH, WithDoc, WithQuery, WithSymbol, WithExamples, WithImports, WithLicenses, WithReadme, WithSize, WithExcludePseudo. Each method ignores options that do not apply to it.

Iterators (auto-pagination)

Each listing endpoint has an All… variant returning a Go 1.25 iter.Seq2[T, error] that lazily follows NextToken across pages:

AllSearch, AllVersions, AllSymbols, AllPackages, AllImportedBy. (Vulns is not paginated — it already returns the full slice — so there is no AllVulns.)

for v, err := range c.AllVersions(ctx, "github.com/samber/lo") {
	if err != nil {
		return err
	}
	fmt.Println(v.Version, v.CommitTime)
}

WithLimit controls the page size; WithToken sets the starting cursor.

🤝 Contributing

# Install dev dependencies
make tools

# Run tests
make test

# Lint
make lint

👤 Contributors

Contributors

💫 Show your support

Give a ⭐️ if this project helped you!

GitHub Sponsors

📝 License

Copyright © 2026 Samuel Berthe.

This project is MIT licensed.

About

📦 Typed Go client for the pkg.go.dev API: search, docs, versions, importers & vulnerabilities

Topics

Resources

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

Sponsor this project

Used by

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.