Library / SDK
googleapis/go-genai avatar
googleapis/go-genai

go-genai: Google's generative model SDK shaped by its own release tooling

Google Gen AI Go SDK provides an interface for developers to integrate Google's generative models into their Go applications.

1,191 stars162 forksGoApache-2.0

At a glance

What is it?
The Go SDK for Gemini is machine generated, ships roughly every week, and has already broken one public method once. Understanding that pipeline explains both what the library gives you and what it will ask you to migrate.
Who is it for?
go-genai is a well-built SDK with an unusual property that deserves to shape how you adopt it: the surface area is decided upstream by a schema and applied here by a generator, so breaking changes arrive on a schedule rather than through a deprecation policy. The practical approach is to pin the version and read the release notes at each bump, which is exactly what the repository's own warning about GenerateVideos is asking you to do.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 17 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One client, two backends, and a constructor that decides everything

The SDK covers two APIs that are sold and documented separately: the Gemini Developer API and the Gemini Enterprise Agent Platform. Rather than ship a separate library for each, the library makes the choice a constructor argument. The Developer API path is an API key and a backend constant.

go
client, err := genai.NewClient(ctx, &genai.ClientConfig{
	APIKey:   apiKey,
	Backend:  genai.BackendGeminiAPI,
})

The Enterprise path replaces the key with a project and a location.

go
client, err := genai.NewClient(ctx, &genai.ClientConfig{
	Project:  project,
	Location: location,
	Backend:  genai.BackendEnterprise,
})

The second one is why `cloud.google.com/go/auth` appears in the dependency list. Authentication is not an SDK concern here, it is delegated, which is the right call for something meant to run on Cloud Run or GKE where the ambient service account is the credential.

For anything past a script, the environment variable route is the one you will end up using, because a config struct with a hardcoded key has no place in a deployed binary. The Developer API needs one variable.

bash
export GOOGLE_API_KEY='your-api-key'

The Enterprise path needs three, and the first is a boolean switch rather than an inference from the others being set.

bash
export GOOGLE_GENAI_USE_ENTERPRISE=true
export GOOGLE_CLOUD_PROJECT='your-project-id'
export GOOGLE_CLOUD_LOCATION='us-central1'

With all of that in place the constructor takes no configuration at all, which is the shape the README shows last.

go
client, err := genai.NewClient(ctx, &genai.ClientConfig{})

That empty struct is worth pausing on, because it is where the SDK and the underlying runtime meet. `base_url.go` sitting in the tree root suggests endpoint construction is separable from credentials, which is what makes local testing against a proxy or a recorded fixture possible.

Multimodal input built from typed parts

The example the README leads with is the one that explains the whole data model. A request is a slice of contents, each content holds parts, and a part is either text or inline binary data.

go
parts := []*genai.Part{
  {Text: "What's this image about?"},
  {InlineData: &genai.Blob{Data: imageBytes, MIMEType: "image/jpeg"}},
}
result, err := client.Models.GenerateContent(ctx, "gemini-flash-latest", []*genai.Content{{Parts: parts}}, nil)

Several things fall out of this. The model name is a plain string argument, which means switching between models is data rather than code, and the README consistently uses the floating alias rather than a pinned snapshot, which is a deliberate choice that trades reproducibility for automatic upgrades. The final nil is the config argument, so anything optional is a struct you can omit entirely.

The `Blob` type carrying both raw bytes and a MIME type is the part that trips people arriving from the Python SDK, where images are often file handles or base64 strings. Here it is bytes and a content type, and you are responsible for matching the two correctly.

For video there is a separate file, `files.go`, and the asynchronous generation path is handled by `operations.go` and `batches.go`, which is the standard Google long running operation pattern. If you are generating video, expect a poll loop rather than a synchronous call.

A breaking change with a version pin attached

This is the most important thing in the README and it is easy to skim, because it is written as a note rather than as a section. The warning says updates to GenerateVideos are coming in an upcoming SDK version, and a small table names exactly what is being removed: the `prompt`, `text` and `image` arguments to `Models.GenerateVideo`, and its asynchronous variants. The migration column points at the `source` argument as the replacement.

The instruction that follows is the part that generalises: to avoid unexpected updates, pin the SDK version to below 2.0.0.

That tells you a great deal about how this library evolves. There is a traditional deprecation window, and then a major version, and then code that no longer compiles. A rename of three arguments on one method is treated as a routine change rather than something requiring a migration period, which is defensible for an SDK this young and fast moving and completely unreasonable for a service you already run in production.

The `go.mod` file records the same philosophy from the other side. It carries a single retraction directive, on version 1.11.0, with the comment that it was retracted due to a breaking change on GenerateVideos. So this has already happened once, on the same method, before the current warning. If you are integrating video generation, plan for that method to change rather than treating it as settled.

Everything else in the recent history is additive. The three most recent releases are a translation config feature, an audio transcription config mode, and a mode enum with `VERBATIM` and `SMART` values added to transcription configs. New surface arrives constantly and old surface is removed on the next major version.

Where the code comes from, judging by the tree

The repository layout makes the generation pipeline visible. `codegen_instructions.md` at the root is the giveaway: there is a document describing how this code is written, which means something writes it. Alongside it sit `release-please-config.json` and `.release-please-manifest.json`, the configuration for automated releases, and a `CHANGELOG.md` whose entries follow the conventional commits format that tool expects.

That combination, generator plus release automation, is what produces the version cadence. Tags v1.69.0, v1.70.0 and v1.71.0 landed on 2026-08-19, 2026-08-25 and 2026-08-31, six days apart each time, and the repository was pushed to on 2026-09-20. This is a library on a weekly train, and treating it like a stable dependency is the first mistake to avoid.

The conversion files support that reading. `live_converters.go` and `tokens_converters.go` sit next to `transformer.go`, which suggests one internal representation converted at the boundary between what the wire format says and what the Go API exposes. Every public method therefore has an adapter, and the adapters are where schema drift becomes a compile error rather than a runtime surprise.

Two directories deserve separate attention. `interactions/` is a nested module holding the newer Interactions API, with its own `models/` subpackages for request and response types. `tokenizer/` is separate again, which reflects that `github.com/eliben/go-sentencepiece` is a direct dependency: token counting is not something the SDK can approximate if you are billing by token or truncating a context window.

The test layout is the other tell. Alongside the ordinary `*_test.go` files sit `replay_api_client.go`, `replay_sanitizer.go` and a `testdata/` directory. Replay-based testing against sanitised recorded traffic is how a generated client can be tested at all, because a generated client has no logic of its own worth testing and everything depends on matching the schema exactly.

The surface area you inherit from a generated client

The root-level files are a map of the API surface, and reading them as filenames tells you what the SDK can do. `models.go` and `models_helpers.go` cover generation, with the helpers file presumably holding convenience wrappers over the raw request types. `chats.go` is multi-turn conversation state. `caches.go` is explicit context caching, which is a real cost lever for anything with a long shared system prompt.

`files.go` handles file upload, which is the alternative to inline data for anything large enough that base64 in a JSON body would be unwise. `documents.go` and `filesearchstores.go` point at a retrieval feature, with the store named separately from the documents it holds, which is the shape of a managed corpus rather than a per-request upload.

`live.go` is the bidirectional streaming API, and it is the one place the dependency list explains itself: `github.com/gorilla/websocket` is there because live sessions are websockets rather than request and response calls. Anything that needs to interrupt a model mid-response, or stream audio both ways, lives behind that file.

`tunings.go` is fine-tuning. `pages.go` is pagination for list endpoints, which is a small sign of care, because hand-written clients usually forget this and it is the first thing that breaks when a corpus grows past one page.

The examples directory mirrors the root-level files one to one, with a folder per capability including `mcptoolbox/`, `live_with_ephemeral_token/` and `interactions/`. A reader can therefore pick the folder matching the API surface they care about and ignore the rest.

What the README does not tell you

There are real gaps, and they cluster in the areas where an SDK is usually judged. There is no error handling guidance beyond `log.Fatal` in the example, no guidance on retries or timeouts, and no statement of whether the SDK retries idempotent calls on your behalf. `common.go` and `api_client.go` almost certainly contain the answers, which means they are discoverable by reading source.

Cost and rate limiting are not mentioned at all. That is arguably correct, since both are properties of the model and the project rather than of the client library, but a Go developer integrating this will want to know whether there is a request queue or whether concurrency control is the application's problem.

There is also no compatibility matrix. The module path is `google.golang.org/genai`, which puts it in the vanity import space reserved for Google's own modules and gives it pkg.go.dev documentation, and the go directive requires Go 1.24. That is a real constraint: an older toolchain in your organisation will not build this without an upgrade.

The Interactions section is the newest surface and the README says so in a note near the top. Its example is a complete program rather than a fragment, which is helpful, and it imports from two subpackages inside the nested module, `interactions/models/interactions` and `interactions/models/operations`. That import depth is a signal that this API is still finding its shape, and that the shape may change without the same ceremony as a major version bump.

Editorial conclusion

go-genai is a well-built SDK with an unusual property that deserves to shape how you adopt it: the surface area is decided upstream by a schema and applied here by a generator, so breaking changes arrive on a schedule rather than through a deprecation policy. The practical approach is to pin the version and read the release notes at each bump, which is exactly what the repository's own warning about GenerateVideos is asking you to do. Start from the two client constructors in the README, since choosing between the Developer API and Enterprise backends is the decision that shapes everything downstream, and treat `genai.NewClient(ctx, nil)` with environment variables as the configuration you will end up with in production anyway.

Frequently asked questions

How do I install and configure the Google Gen AI Go SDK?

Add it with go get google.golang.org/genai and import google.golang.org/genai. You then construct a client with genai.NewClient, either with an APIKey and Backend set to BackendGeminiAPI, or with Project, Location and Backend set to BackendEnterprise. Configuration can also come entirely from environment variables, which is what the empty ClientConfig constructor example in the README relies on.

What breaking change should Go developers watch for in go-genai?

The README warns that an upcoming version changes GenerateVideos: the prompt, text and image arguments to Models.GenerateVideo and its async variants are being removed in favour of a source argument. It advises pinning to a version below 2.0.0 to avoid unexpected updates. A retraction already exists in go.mod for v1.11.0 over a breaking change on the same method.

Which APIs does the Go SDK support?

Two: the Gemini Developer API and the Gemini Enterprise Agent Platform, selected through the Backend field on ClientConfig. It also supports the newer Interactions API for multi-turn conversation with models and agents, which lives in a nested interactions module with its own request and operation types.

What Go version and dependencies does go-genai require?

The go.mod declares go 1.24, so an older toolchain will need an upgrade. Direct dependencies include cloud.google.com/go and its auth package, gorilla/websocket for the live bidirectional API, go-sentencepiece for tokenization, and go-cmp and testify for testing.

Official sources

  1. googleapis/go-genai on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/googleapis-go-genai.svg)](https://hysenlabs.com/projects/googleapis-go-genai)