Open-source project
grpc/grpc avatar
grpc/grpc

grpc: one C++ core, two families of language libraries

GitHub describes it as C++ based gRPC (C++, Python, Ruby, Objective-C, PHP, C ). The repository metadata lists C++ as its primary language. The metadata lists the Apache-2.0 license. This article stays within the project description and details documented in the GitHub repository README.

45,349 stars11,381 forksC++Apache-2.0

At a glance

What is it?
grpc/grpc holds a shared C++ core and six language libraries bound to it, while Java, Kotlin, Go, Node, WebJS, Dart, .NET and Swift live in repositories of their own. The two families ship on different release trains, and the C++ path needs a compiler, a generated Makefile and a source checkout.
Who is it for?
grpc fits a polyglot team that has chosen RPC over HTTP and JSON and wants one wire contract across services, with the caveat that the core-bound languages and the standalone ones ship from different repositories.
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 2 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

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

Editorial analysis

Six languages ride the C++ core, eight do not, and they move on separate trains

The About This Repository section draws the line that matters. gRPC contains source for libraries in several languages written on top of a shared C++ core library at src/core: the core itself, C++, Ruby, Python, PHP, a C# library based on the core, and Objective-C. A second table lists what lives elsewhere: Java and Kotlin in their own repositories, Go in grpc-go, NodeJS in grpc-node, WebJS in grpc-web, Dart in grpc-dart, .NET as a pure C# implementation in grpc-dotnet, and Swift in grpc-swift.

So `pip install grpcio` and `go get google.golang.org/grpc` are not two front doors to the same thing. The Python wheel embeds the C core, while the Go library is its own implementation with its own release cadence, its own issue tracker and its own maintainers. A team with services in both is depending on two release trains, and a gRPC breaking change has to be evaluated twice.

The README is direct about the unevenness, saying libraries in different languages may be in various states of development. It also carries a GOVERNANCE.md and a MAINTAINERS.md, which is where you would go to find out who owns which of the fourteen.

Eleven install lines, and two of them send you into the source tree

The onboarding section is a table of package manager commands, which is the most useful thing in the README:

bash
pip install grpcio
gem install grpc
pecl install grpc
go get google.golang.org/grpc
npm install @grpc/grpc-js

The .NET packages are named separately as Grpc.Net.Client and Grpc.AspNetCore.Server, Dart is the pub package grpc, and Java and Kotlin are JARs from Maven Central rather than a command. Objective-C adds a gRPC-ProtoRPC dependency to a podspec.

Two entries break the pattern. C++ says to follow the instructions under the src/cpp directory, and Objective-C points at src/objective-c. Those are not package installs, they are directions to read a build system inside the repository, and a C++ user therefore needs a compiler, Bazel or CMake, and a checkout before anything runs, while a Python user needs a wheel. The README does not summarise what the C++ build requires, it delegates to the directory.

Per-language quickstarts live on the grpc.io documentation site rather than in the repository, so the README is an index of where to go next rather than a tutorial.

The Makefile is generated, so a hand-edit is lost on the next regeneration

The Makefile at the root opens with a warning that is easy to skim past. It was automatically generated from a template file, the header says to look in the templates directory instead, and it can be regenerated by running tools/buildgen/generate_projects.sh. The build for C and C++ code is described in the same comment as currently handled by that file.

That matters for anyone who lands in a C++ build problem and starts editing targets. The edit works until the next regeneration, which happens as part of normal development, and then the change is gone with no warning in the diff beyond the generator output.

The generated content is also where the platform assumptions live. HOST_SYSTEM comes from uname, MSYS and MINGW64 are both rewritten to MINGW32, and the compiler is probed in order: cc first, then gcc, then clang, with a no_c_compiler fallback if none of them answer. BINDIR resolves to a b directory beside the Makefile. A Windows user under MSYS or MINGW64 lands in the MINGW32 path regardless of which of the two they actually have, and that decision is made in a file you are not supposed to edit.

The root is a union of every language's build system, so a clone buys all of them

Count what sits at the top of the repository and the shape of the project becomes clear. There is composer.json, config.m4 and config.w32 for PHP, a Gemfile and Rakefile plus build_config.rb for Ruby, gRPC-C++.podspec for CocoaPods, Package.swift and BoringSSL-Package.swift for the Swift package manager, .pylintrc, .yapfignore and .istanbul.yml for Python, .rspec for Ruby specs, and .clang-format and .clang-tidy for the C++ side. There is also bazel/, MODULE.bazel, WORKSPACE, .bazelversion and .bazelci/.

Every one of those files is load-bearing for a language you may not use. There is no subtree to take, so a team that only wants the C++ core and has no intention of running the PHP extension still clones the PHP build metadata, the Ruby Rakefile and the Swift manifest. Vendoring gRPC into an internal mirror means copying directories by hand rather than adding a subtree, and the build files that come along are the ones you did not ask for.

The linting and style configuration is spread the same way, which tells you the project expects a contributor working in one language to be checked by that language's tools. It is a wide surface for a repository whose runtime dependency graph is really just the core.

setup.py patches the compiler so BoringSSL assembly files build at all

The Python package is a C extension, and the packaging reflects that. setup.py imports the Unix C compiler from distutils and appends .S to the accepted source extensions, with a comment saying it monkey-patches the compiler to accept the ASM files used by Boring SSL:

python
UnixCCompiler.src_extensions.append(".S")

Without that line the BoringSSL sources do not compile on a Unix build. The same file redirects the manifest template to PYTHON-MANIFEST.in and sets the include path to third_party/abseil-cpp, third_party/address_sorting and third_party/cares, so the build expects submodules present next to the source. A .gitmodules file at the root is the visible half of that arrangement.

The practical consequence is a split in how you obtain grpcio. If a wheel covers your interpreter and platform, none of this runs and the install is a one-liner. If it does not, you are compiling C against Abseil, c-ares and BoringSSL with a specific setuptools, and pyproject.toml is explicit that the build backend needs setuptools>=77.0.1, wheel and Cython~=3.2 before anything is compiled. grpcio is not a pure Python dependency wearing a C costume.

requirements.txt pins Cython to one version and holds protobuf below 8

The Python setup requirements are seven lines and three of them are exact or bounded:

bash
build>=1.3.0
coverage>=7.9.0
cython==3.2.8
protobuf>=7.35.1,<8.0.0
typing-extensions==4.12.2
wheel>=0.29
setuptools>=77.0.1

Cython is pinned to one patch release, typing-extensions to one release, and protobuf is given a ceiling at the 8.0 line. These are the inputs to a source build of the package, so the ceiling decides which protobuf your compiled grpcio is generated against rather than what your application pulls in later.

Elsewhere the same file family is equally tight in a different way. pyproject.toml takes its version dynamically from a grpc_version.VERSION attribute rather than writing a number in the file, packages from src/python/grpcio, and excludes the Cython sources from the package data while keeping the prebuilt windows binaries and the credentials file _credentials/roots.pem alongside them. A Python team that wants to track the repository has to keep a source build environment in step with these pins, or take the wheel and let the release do it.

Master is built daily, and a release is preceded by two pre-releases

Two things in the README shorten the distance between a commit and something you can install. Precompiled bleeding-edge builds of the master branch HEAD are uploaded daily to packages.grpc.io, and the performance dashboard reports numbers for those master branch daily builds rather than for a released version.

The release history shows the same rhythm at the version level: v1.84.0-pre1 on 2026-09-01, v1.84.0-pre2 on 2026-09-09, and v1.84.0 on 2026-09-11. A pre-release pair roughly a week apart, then a final two days after the second. The last push to the default branch, master, was on 2026-09-28, and the repository is not archived.

That is a fast project, and the fast part has a cost. A daily master build means you can run code that has never carried a tag, which is exactly what you want to reproduce a bug and exactly what you do not want under a production release process. The performance numbers are for master as well, so a regression in a released version is not something that dashboard would have shown you.

examples/ has android in it, and no Android library in either table

The examples directory holds android, cpp, csharp, node, objective-c, php, protos, python and ruby. Cross that against the two language tables and the mismatch is instructive: the directories cover the in-repo languages plus Node, while the libraries for Java, Kotlin, Go, WebJS, Dart, .NET and Swift are elsewhere and their examples are not here.

Android is the interesting case. examples/android exists, but Android is not in either table: the client libraries that would serve it are grpc-java and grpc-kotlin, both in other repositories. So the one example directory with no matching library in this repository is the mobile one.

For most readers that is not a problem, because the examples/protos directory is where the mechanism is, and a service definition in a .proto file is language independent. The practical rule is that you read the protos here for how a service is declared, and you read the example in your own language's repository for how that runtime wires it up. The README does not draw that line for you, and a newcomer looking for a Java example in this tree will not find one.

Editorial conclusion

grpc fits a polyglot team that has chosen RPC over HTTP and JSON and wants one wire contract across services, with the caveat that the core-bound languages and the standalone ones ship from different repositories. It does not fit a team that wants a single monorepo-wide upgrade or a build without a toolchain, because the Makefile is generated and the Python package compiles C. Verify first which of your languages is served by src/core and which by its own repository, since that decides both the package you install and the release train you track.

Frequently asked questions

grpc explained

The repository describes gRPC as a remote procedure call framework that can run anywhere, and as an RPC library and framework. Its stated role is to let client and server applications communicate transparently and to simplify building connected systems, and the project also says it is high-performance, which is a claim the README does not back with numbers.

grpc examples

The examples directory at the repository root holds android, cpp, csharp, node, objective-c, php, protos, python and ruby. Per-language quickstarts and tutorials are on the grpc.io documentation site, and the examples for Java, Kotlin, Go, WebJS, Dart, .NET and Swift live in those languages' own repositories rather than here.

What does gRPC stand for?

The repository expands only the RPC part, describing gRPC as a remote procedure call framework and titling itself an RPC library and framework. It does not spell out what the g and the P stand for, so that part is not answered anywhere in the README.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
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/grpc-grpc.svg)](https://hysenlabs.com/projects/grpc-grpc)