Open-source project
storj/drpc avatar
storj/drpc

drpc, a small Go RPC framework that gRPC servers can talk to without a rewrite

drpc is a lightweight, drop-in replacement for gRPC

1,636 stars65 forksGoMIT

At a glance

What is it?
drpc is a lightweight, drop-in replacement for gRPC in Go, with three dependencies and a few thousand lines of code. It uses a faster wire format, is transport agnostic, supports middleware, and can serve gRPC and drpc on the same port so a migration does not have to be a flag day. It is MIT licensed and was built at Storj, where it has run in production for years.
Who is it for?
Adopt drpc if you are running Go services where gRPC's dependency weight and allocation profile are the problem, and you can tolerate a protocol that is not gRPC on the wire, since drpc speaks its own format. Skip it if interoperability with other languages is a hard requirement, because the native implementations for C++, Rust and Node are all marked incomplete.
Can I use it commercially?
Yes. MIT 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 34 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 November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • storj/drpc1,636 ★ · +3
Star history
Repository2026-10-162026-11-07
storj/drpc1.6k1.6k

3 Stars in the last 22 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Small on purpose, and the dependency count is the point

The highlights list leads with simplicity, at just a few thousand lines of code, and the second item is the small dependencies: only 3 requirements in go.mod, and 9 lines of go mod graph. The module file confirms it, with zeebo/assert, zeebo/errs and google.golang.org/protobuf as the only requires, on Go 1.19. That is an unusual position for an RPC framework, since gRPC's own dependency tree is the thing many Go teams object to. The other highlights are compatibility, since it works for many gRPC use-cases as-is, extensibility, since it is transport agnostic, supports middleware and is designed around interfaces, and the production claim, that it has been used in production for years across tens of thousands of servers. The package path is storj.io/drpc, the licence is MIT, and the last push was on 2026-10-05.

go
module storj.io/drpc

go 1.19

require (
	github.com/zeebo/assert v1.3.0
	github.com/zeebo/errs v1.2.2
	google.golang.org/protobuf v1.27.1
)

The wire format is the real difference

The claim of being fast rests on the wire format, which is documented separately in the project wiki as a lightning quick design. This is the point to understand before evaluating anything else, because it is what separates drpc from gRPC rather than what improves it. drpc is a drop-in replacement at the API and use-case level, not at the protocol level. A drpc client cannot talk to a gRPC server without a bridge, and the reverse is also true, which is why the migration story in this project is built around serving both protocols on the same port rather than around the client. The examples directory makes that concrete, with a basic client and server, a client and server that also serve a Twirp or grpc-web compatible HTTP server on the same port, a case serving gRPC and DRPC on the same port, and an OpenTelemetry example.

code
A basic drpc client and server
Serving gRPC and DRPC on the same port

The package layout, and the boundaries it draws

The top level of the repository is a list of small packages, and the naming makes the architecture legible. drpcconn handles connections, drpcserver and drpcctx the server side and the request context, drpcstream the streaming calls, drpcwire the wire format, drpchttp the HTTP transport including the package that other-language clients use, drpcenc the encoding, drpcerr the error types, drpcmetadata the metadata handling, drpcmanager and drpcmux the management and multiplexing pieces, drpcpool the connection pool, drpcsignal the signal handling, drpcstats the statistics, drpccache the caching, drpcmigrate the gRPC migration support, drpcdebug the debugging helpers, and drpctest the test helpers. There is also a cmd/ directory for the binaries and an internal/ directory. The presence of drpcmigrate as a first class package is the clearest signal that the gRPC transition was planned rather than bolted on.

code
drpcconn/
drpcserver/
drpcctx/
drpcstream/
drpcwire/
drpchttp/
drpcenc/
drpcerr/
drpcmetadata/
drpcmanager/
drpcmux/
drpcpool/
drpcsignal/
drpcstats/
drpccache/
drpcmigrate/
drpcdebug/
drpctest/

Interoperability, and where it is incomplete

The other languages section is honest about its state. DRPC can be made compatible with RPC clients generated from other languages, with Twirp clients and grpc-web clients able to talk against the drpchttp package. Native implementations can have some advantages, and support for other languages is in progress in various states of completeness, which the project invites people to help with through its Zulip chat. The table gives the status: C++ in a repository under storj, Rust under zeebo, and Node under mjpitz, and all three are marked Incomplete. So the practical interoperability story today is that a Twirp or grpc-web client can talk to a drpc server, that a drpc server can sit beside a gRPC server on one port, and that native clients in other languages are a work in progress rather than a dependency you can take today.

code
| Language | Repository                          | Status     |
| C++      | https://github.com/storj/drpc-cpp   | Incomplete |
| Rust     | https://github.com/zeebo/drpc-rs    | Incomplete |
| Node     | https://github.com/mjpitz/drpc-node | Incomplete |

External packages fill in the production gaps

Two external packages extend the core, and reading what they add tells you what the core deliberately leaves out. The bryk package adds simplified TLS setup for both client and server, server middleware including basic components for logging, token-based auth, rate limit and panic recovery, client middleware including logging, custom metadata and panic recovery, bi-directional streaming over upgraded HTTP(S) connections using WebSockets, and concurrent RPCs via a connection pool. The elara package adds concurrent RPCs based on yamux and simple drop-in replacements for the server and connection types. So the core is a transport and protocol layer, and the operational concerns, TLS, middleware, streaming over websockets and pooling, are things the ecosystem provides. The project asks that an issue be opened or a chat message sent if you would like to be featured in that list, which tells you the extension ecosystem is curated rather than accidental.

code
- Simplified TLS setup (for client and server)
- Server middleware, including basic components for logging, token-based auth,
  rate limit, panic recovery, etc
- Bi-directional streaming support over upgraded HTTP(S) connections using WebSockets
- Concurrent RPCs via connection pool

The benchmarks, read with their caveats

The benchmark table is large and the caveats are stated before it, which is the right order. The project says the microbenchmarks attempt to provide a comparison and come with some caveats. First, they do not send data over a network connection, which is expected to be the bottleneck almost all of the time. Second, no attempt was made to run them in a controlled environment, with CPU scaling disabled and noiseless. Third, no tuning was done to ensure both are performing optimally, so there is an inherent advantage for DRPC because the author is familiar with how it works. The numbers themselves are large in both directions, with the unitary case reported at 29.7 microseconds per operation for gRPC against 8.3 for drpc, and the memory per operation at 9.42kB against 1.42kB in the small case. Taken with the caveats, they indicate a materially lighter implementation rather than a precise performance guarantee.

The build pipeline, and the release gap

The Makefile shows a project with a thorough CI setup, and the vet target is the most revealing part of it. The default goal runs tidy, docs, generate, lint, vet and test, and the vet target runs go vet for the native platform and then for a matrix of cross-compilation targets, covering linux on 386, amd64, arm and arm64, windows on 386, amd64 and arm64, and darwin on amd64 and arm64. The test target runs the suite with the race detector, and then runs integration-tagged variants twice, once with the gogo tag and once with a custom tag, which is how the alternative implementations get exercised. Lint runs staticcheck and golangci-lint plus repository-specific checks for copyright headers, large files, import rules and atomic alignment. The release history is the one oddity: v1.0.0 in May 2026, preceded by v0.0.20 in March 2021 and v0.0.9 in February 2020, so the project sat at a pre-1.0 tag for years and then made a single jump to 1.0.

make
all: tidy docs generate lint vet test

vet:
	./scripts/run.sh '*' go vet ./...
	GOOS=linux   GOARCH=arm64 ./scripts/run.sh '*' go vet ./...

Editorial conclusion

Adopt drpc if you are running Go services where gRPC's dependency weight and allocation profile are the problem, and you can tolerate a protocol that is not gRPC on the wire, since drpc speaks its own format. Skip it if interoperability with other languages is a hard requirement, because the native implementations for C++, Rust and Node are all marked incomplete. Verify three things before you plan a migration: that a gRPC client can still reach your service, which the drpchttp package covers for Twirp and grpc-web clients but not for arbitrary gRPC clients; that the benchmarks are read with their caveats, because the project states they do not send data over a network and that no tuning was done for gRPC; and that the v1.0.0 tag from May 2026 matches your expectations, since the previous release was v0.0.20 in 2021.

Frequently asked questions

What is drpc and what does it replace?

It is a lightweight, drop-in replacement for gRPC written in Go, in a few thousand lines of code with only three requirements in go.mod. It is transport agnostic, supports middleware, is designed around interfaces, and uses its own faster wire format rather than the gRPC one.

Can a drpc server still serve gRPC clients?

The examples include serving gRPC and DRPC on the same port, so a migration does not have to be a flag day. Twirp and grpc-web clients can also be used against the drpchttp package, while native implementations for C++, Rust and Node are all marked Incomplete in the project's own table.

What does the drpc dependency set look like?

The module file requires only zeebo/assert, zeebo/errs and google.golang.org/protobuf, on Go 1.19, and the project highlights the small dependencies as a feature, noting only 3 requirements in go.mod and 9 lines of go mod graph.

How should the drpc benchmarks be read?

With their caveats, which the project states up front: they do not send data over a network connection, they were not run in a controlled environment, and no tuning was done so that gRPC performs optimally, which gives DRPC an inherent advantage. The reported figures show lower time per operation and lower memory per operation for drpc across the size classes.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. storj/drpc on GitHub
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/storj-drpc.svg)](https://hysenlabs.com/projects/storj-drpc)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/storj-drpc.svg)](https://hysenlabs.com/projects/storj-drpc)

Was this useful?