Library / SDK
googleapis/google-cloud-cpp avatar
googleapis/google-cloud-cpp

google-cloud-cpp gives C++ teams one idiomatic client per Google Cloud service

C++ Client Libraries for Google Cloud Services

660 stars475 forksC++Apache-2.0

At a glance

What is it?
The googleapis/google-cloud-cpp repository packages a C++ client library for each Google Cloud Platform service, each with its own quickstart and CMake or Bazel build files. The price of that coverage is a large surface, a versioned migration path, and per-service documentation rather than one manual.
Who is it for?
Adopt google-cloud-cpp when your team already writes C++ and needs to call Google Cloud services without hand rolling REST clients, and when you are willing to read a separate README and quickstart per service.
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 received new commits within the last day.
What is it written in?
Mainly C++, according to GitHub's language statistics.

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

Editorial analysis

One repository per service means one README per service

The organising idea is breadth rather than depth. The repository contains idiomatic C++ client libraries for a long list of Google Cloud Platform services, and the listing shows them as separate directories under google/cloud/, one per service: accessapproval, accesscontextmanager, apikeys, asset, bigtable, pubsub, spanner, storage and many more. Each carries its own README.md with a quickstart link and a reference link to cloud.google.com/cpp/docs/reference. The top level README is explicitly auto generated by ci/test-markdown/generate-readme.sh, or rather by ci/test-markdown/generate-readme.sh, so the file you read at the root is a generated index rather than a hand written narrative. That has an immediate consequence for anyone evaluating the project. There is no single manual that explains the whole thing. You pick a service, then you read that service's README, then you run the program in its quickstart directory. The same applies to build integration, which each library's README covers under how to incorporate the library into your build system.

The quickstart directories carry the CMake and Bazel build files

The entry point for each library is a directory named quickstart/, and the README describes its purpose as helping you get up and running in a matter of minutes. Inside sits a minimal Hello World program for that service plus minimal build files for common build systems, specifically CMake and Bazel. The example the README shows comes from Google Cloud Storage and is the clearest picture of the calling convention. The client is constructed from an options object, and by default it uses the default configuration for authentication and project id, which means you do not hand a credential to the constructor.

cpp
#include "google/cloud/storage/client.h"
#include "google/cloud/common_options.h"
#include <cstdlib>
#include <iostream>
#include <string>

int main(int argc, char* argv[]) {
  if (argc != 2) {
    std::cerr << "Missing bucket name.\n";
    std::cerr << "Usage: quickstart <bucket-name>\n";

The program takes the bucket name from the command line and exits with a usage message if the argument is missing.

Options objects carry the CA bundle override the CI environment needs

The interesting detail in that quickstart is the authentication plumbing, which is expressed as a set of typed options rather than a raw parameter. The client starts from google::cloud::Options{} and then has individual options applied to it. The example handles the case where the CURL_CA_BUNDLE environment variable is set, and it explains why: the bundle is required for the Windows CI environment where standard system roots may not be sufficient or accessible by the hermetic build.

cpp
  // Create a client to communicate with Google Cloud Storage. This client
  // uses the default configuration for authentication and project id.
  auto options = google::cloud::Options{};

  // If the CURL_CA_BUNDLE environment variable is set, configure the client
  // to use it. This is required for the Windows CI environment where standard
  // system roots may not be sufficient or accessible by the hermetic build.
  auto const* ca_bundle = std::getenv("CURL_CA_BUNDLE");
  if (ca_bundle != nullptr) {
    options.set<google::cloud::CARootsFilePathOption>(ca_bundle);
  }

  auto client = google::cloud::storage::Client(options);

That single pattern, an options object with typed setters, is how configuration reaches the client. It is also the extension point to reach for when a deployment needs a different trust store, since the environment variable path is the documented pattern rather than an accident of the sample.

Streaming write and read return objects you must check

The write path in the example is a stream, not a one-shot call. WriteObject is given a bucket name and an object name and returns a writer, the text is streamed into it, and Close is called before the result is inspected.

cpp
  auto writer = client.WriteObject(bucket_name, "quickstart.txt");
  writer << "Hello World!";
  writer.Close();
  if (!writer.metadata()) {
    std::cerr << "Error creating object: " << writer.metadata().status()
              << "\n";
    return 1;
  }
  std::cout << "Successfully created object: " << *writer.metadata() << "\n";

  auto reader = client.ReadObject(bucket_name, "quickstart.txt");
  if (!reader) {
    std::cerr << "Error reading object: " << reader.status() << "\n";
    return 1;
  }

The error handling pattern here is worth copying exactly. After Close, the code checks whether writer.metadata() is present and only dereferences it inside the success branch, so a failed upload does not crash on a missing value. The same shape appears on the read side, where the reader is tested for truthiness before any data is pulled from it.

A v3 major version means existing callers carry migration debt

The README points applications at a migration guide before anything else. It says to refer to the V3 Migration Guide for details on updating existing applications using v1.x.y or v2.x.y, and it separately asks you to check the CHANGELOG for important announcements and upcoming changes. That is the sharpest edge of this project for anyone who has already shipped code against it. A major version bump in a client library means the call sites, the option types and the error handling may all have moved, and the guide is a document you have to read rather than a compatibility promise. Release cadence is fast. The recent tags are v3.10.0 on 2026-09-15, v3.11.0 on 2026-10-02 and v3.12.0 on 2026-10-12, and the last push was on 2026-10-20. Several releases a month means you are choosing how closely you track it, and the CHANGELOG is the place where breaking changes get announced.

Build support is split across Bazel, CMake and vcpkg, and CI guards the style

The repository layout shows a build system that has to satisfy several consumers at once. There is a BUILD.bazel, a MODULE.bazel, a WORKSPACE.bazel, a WORKSPACE.bzlmod, a CMakeLists.txt and a libraries.bzl file, so Bazel and CMake are both first class. A vcpkg.json file sits at the top level, which is the packaging route for people who consume these libraries through vcpkg rather than from source. The CI setup is visible in the file names as well: badges for GCB CI status appear twice, once for clang-tidy and once for asan, plus a GitHub Actions badge and a Codecov coverage badge. The presence of .clang-format, .clang-tidy, .cmake-format.py, .editorconfig and .typos.toml in the root tells you the project enforces formatting and lint rules on contributions, so a patch that does not match those settings will be rejected by the automated checks. The quickstart build files are the cheapest way to see which of the two build systems a given library expects.

Where the alternative fits and where it does not

The realistic alternative for a C++ codebase is not another C++ library but a different language boundary: call the service over HTTP from your own code, or move the integration into a service written in a language with a published Google Cloud client and expose your own service to C++ callers. The difference in approach is stark. The generated clients in this repository give you typed request and response objects, per-operation error statuses surfaced through the metadata and status accessors shown above, and streaming primitives for object transfer, none of which you would write by hand. The cost is coupling: your build now pulls these libraries, your release cycle has to absorb their major versions, and the surface you depend on is the union of many service specific APIs rather than one consistent shape. For a team that only needs one service, reading one README and one quickstart is a fair price. For a team that needs a dozen, the per-service model becomes a documentation and review burden that a single HTTP wrapper of your own would avoid.

Editorial conclusion

Adopt google-cloud-cpp when your team already writes C++ and needs to call Google Cloud services without hand rolling REST clients, and when you are willing to read a separate README and quickstart per service. It is the wrong choice for a project that wants one uniform API across every service, and the wrong choice if you cannot absorb a v3 migration for code written against v1.x.y or v2.x.y. Verify first that your service has a GA library here, read doc/v3-migration-guide.md before porting existing code, and check the CHANGELOG for the announcements the README warns about, since v3.12.0 shipped on 2026-10-12 and the last push was on 2026-10-20.

Frequently asked questions

How do I get started with a googleapis/google-cloud-cpp library?

Each library has a directory named quickstart/ that contains a minimal Hello World program and minimal build files for CMake and Bazel. The README states that this directory is intended to help you get up and running in a matter of minutes.

How do I configure authentication and the CA certificate bundle in google-cloud-cpp?

The client is built from a google::cloud::Options object, and the quickstart example uses the default configuration for authentication and project id. When CURL_CA_BUNDLE is set, the example applies it through google::cloud::CARootsFilePathOption, which is required for the Windows CI environment where system roots may not be sufficient.

What do I need to change to move an application from google-cloud-cpp v2 to v3?

The README refers readers to the V3 Migration Guide for details on updating existing applications that use v1.x.y or v2.x.y, and it also asks users to check the CHANGELOG for important announcements and upcoming changes.

Which Google Cloud services have libraries in googleapis/google-cloud-cpp?

The repository lists a separate directory per service under google/cloud/, including accessapproval, apikeys, asset, bigtable, pubsub, spanner and storage among others. The README describes the libraries as GA and supported by Google unless a library's own README.md notes otherwise.

Can I use google-cloud-cpp with CMake instead of Bazel?

Yes. The repository root contains both CMakeLists.txt and BUILD.bazel, and the quickstart directory of each library contains minimal build files for common build systems such as CMake and Bazel. A vcpkg.json file is also present for consumers who package the libraries with vcpkg.

Official sources

  1. googleapis/google-cloud-cpp 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-google-cloud-cpp.svg)](https://hysenlabs.com/projects/googleapis-google-cloud-cpp)

Was this useful?