CLI tool
timostamm/protobuf-ts avatar
timostamm/protobuf-ts

protobuf-ts: TypeScript Code Generation for Protobuf and RPC

Protobuf and RPC for TypeScript

1,345 stars151 forksTypeScriptApache-2.0

At a glance

What is it?
protobuf-ts turns `.proto` schemas into TypeScript or JavaScript message code and transport clients for gRPC, gRPC Web, Twirp, and Node.js gRPC. It fits teams that want typed serialization without hand-maintaining codec classes, but schema generation still requires `protoc` and an understanding of protobuf wire compatibility.
Who is it for?
protobuf-ts is a practical choice for TypeScript services and browser clients that already define interoperability through `.proto` files, especially where BigInt, unknown fields, proto3 optional values, or several RPC transports matter. It is less suitable for projects that want schema-free TypeScript interfaces or cannot add `protoc` to their development workflow.
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 93 days ago.
What is it written in?
Mainly TypeScript, 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

Why protobuf-ts Exists for TypeScript Projects

protobuf-ts addresses the gap between `.proto` schemas and TypeScript code that remains typed without making developers maintain serialization logic by hand. A schema defines messages such as `Person`, while generated code exposes methods for converting those values to bytes and back. The same schema can also produce RPC clients and servers, so the wire contract remains in the protobuf definition instead of becoming a separate TypeScript-only interface.

The intended users are Node.js and browser developers who need Protocol Buffers or RPC in a TypeScript codebase. The project is also relevant to teams using Twirp or gRPC and to organizations that need generated reflection information, including custom options. Its browser support makes it different from tools centered only on a Node.js server. The README states that the implementation is pure TypeScript and supports both TypeScript and JavaScript output.

This is not a general-purpose schema validator or an automatic replacement for service design. It begins with `.proto` input. Teams that define only TypeScript types and never exchange a protobuf-compatible format will receive limited value from this tool. The project is better understood as a code generator and runtime support layer for protobuf workflows than as an RPC server framework by itself.

Schema-to-TypeScript Data Flow and Runtime Surface

The core flow begins with a protobuf schema such as `Person`, whose fields include `string`, `uint64`, `int32`, and optional bytes. `protobuf-ts` generates a TypeScript representation with message methods. In the README example, a value uses `id: 123n`, demonstrating the project's BigInt representation for 64-bit integers. Calling `Person.toBinary(pete)` produces a binary payload, and `Person.fromBinary(bytes)` reconstructs a typed value.

JSON is handled separately through `Person.fromJsonString`, which accepts the canonical proto3 JSON representation documented in the MANUAL. The feature list says the project implements that format, the protobuf binary format, and unknown-field handling. Generated message types also provide comparison, cloning, merging, and type-guard methods. These operations reduce the amount of application code devoted to common message handling.

RPC generation follows the same schema-driven approach. The README lists generated clients for gRPC Web, Twirp, and gRPC, as well as native gRPC servers and clients for `@grpc/grpc-js`. The repository contains separate packages for runtime support and these transports. That package split matters when adopting the project: serialization support and a particular network transport are related, but they are not necessarily the same dependency or execution path. The MANUAL is the appropriate place to determine which package and client form match a deployment.

Installation and the First Generated Message

The README's quickstart installs the generator plugin and the protobuf compiler as development dependencies. It then expects the example schema to be placed in a `protos/` directory. The commands below are copied from the documented workflow.

bash
npm install --save-dev @protobuf-ts/plugin protoc

After placing `msg-readme.proto` in `protos/`, generate a TypeScript file with:

bash
npx protoc --ts_out . --proto_path protos protos/msg-readme.proto

The README says this generates `msg-readme.ts`. The generated file can then be imported into application code, where the message shape and conversion methods become available. The schema used in the README is:

proto
syntax = "proto3";

message Person {
    string name = 1;
    uint64 id = 2;
    int32 years = 3;
    optional bytes data = 5;
}

The first real use is therefore schema compilation, followed by importing the generated module. The README's example creates `pete`, converts it with `Person.toBinary`, restores it with `Person.fromBinary`, and separately parses JSON with `Person.fromJsonString`. If the local `protoc` asks for it, add `--experimental_allow_proto3_optional`, as the quickstart notes for proto3 optional fields.

gRPC, gRPC Web, Twirp, and Node Server Choices

protobuf-ts covers several RPC arrangements, but it does not make the deployment topology irrelevant. The README distinguishes browser-oriented gRPC Web clients, Twirp clients, and gRPC clients from native Node.js server and client support through `@grpc/grpc-js`. The repository layout reinforces this separation with packages including `grpc-transport`, `grpcweb-transport`, `twirp-transport`, `grpc-backend`, and `runtime-rpc`.

That separation gives teams a choice of transport rather than forcing one protocol into every target. A browser client cannot simply be treated as a native Node.js client because the transport and runtime assumptions differ. Twirp support is also listed as usable with Twirp-TS servers running on Node.js, while native gRPC examples are present in the repository.

The trade-off is that code generation alone does not remove RPC configuration work. The README points readers to the MANUAL for transport-specific instructions, and the available top-level examples show several client and server arrangements. Before selecting a transport, confirm whether the deployment uses browser networking, a Node.js server, or both. Also check how the generated client is connected to a concrete server address and how errors are handled. Those details are not fully specified by the quickstart.

Performance, Code Size, and Compatibility Choices

The feature list gives protobuf-ts an explicit speed versus code-size decision. MANUAL.md includes a section titled “code size vs speed,” and the repository includes separate test packages for forcing speed or code-size optimization, including variants with long type strings. This indicates that generation mode is treated as a project-level choice rather than an invisible implementation detail.

The project also documents support for `bigint`, proto3 optionals, standard TypeScript enums, well-known types, custom JSON representations, and unknown fields. Those features affect application design. A TypeScript consumer must be prepared for `bigint` for `uint64` values, optional bytes are represented according to generated schema conventions, and custom protobuf options can be exposed through reflection information.

The README claims strict conformance to the protobuf specification, but adoption should not treat that statement as a substitute for checking generated output. Schema evolution, compiler compatibility, and the behavior of the selected transport remain separate concerns. The project can generate JavaScript as well as TypeScript, which may help browser bundling workflows, but it also means the generated artifact should be checked against the application's module format and build configuration.

Licensing and Repository Maintenance Boundaries

The root package identifies the project license as `(Apache-2.0 AND BSD-3-Clause)`. The README gives more detail: most files are under Apache-2.0, while specific runtime files and bundled proto material carry BSD-3-Clause or mixed notices from their respective copyright holders. It specifically identifies UTF8 decoding code, varint code, gRPC status codes, Twirp error codes, and Google proto files as separately attributed components.

Those notices affect how a distribution is assembled. A team should preserve the relevant license files and attribution when publishing generated or derived artifacts. This article does not provide legal advice, and the repository's own notices should be reviewed for the exact files included in a release. The point for technical decision making is that the project is not represented as a single undifferentiated license blob. Dependency and generated-code review should account for both Apache-2.0 and BSD-3-Clause material.

The repository is not archived. Its last push was on 2026-07-22, so it has recent repository activity relative to the listed releases, although the latest listed release is `v2.11.1` from 2025-06-18. Upgrade planning should therefore compare the installed package version with release notes and the MANUAL rather than assuming that every repository change is a published package update.

Adoption Boundaries for protobuf-ts

The clearest limitation is that protobuf-ts is tied to protobuf schema tooling. Installation requires `@protobuf-ts/plugin` and `protoc`, and the documented generation command depends on `protoc` accepting the schema and its command-line flags. Teams that prohibit a native compiler, require a completely schema-free build, or cannot accommodate generated source code will face an avoidable workflow cost.

There is also a distinction between supported capability and documented setup. The README lists many transport and reflection features, but it does not provide a single universal client configuration for every server type. The MANUAL and transport packages are part of the product, not optional background reading when a team depends on native gRPC, gRPC Web, or Twirp. The examples in the repository can guide the choice, but the README does not claim that all transports behave identically.

A real alternative is to use another TypeScript RPC approach that defines request and response contracts directly in TypeScript and uses a web-oriented client without the protobuf code-generation step. That removes `protoc` and protobuf wire compatibility from the path, but it does not provide the same cross-language `.proto` contract, canonical proto3 JSON behavior, or generated binary codec. The right comparison is protobuf interoperability versus generator-free TypeScript ergonomics, not simply which package has more features.

Editorial conclusion

protobuf-ts is a practical choice for TypeScript services and browser clients that already define interoperability through `.proto` files, especially where BigInt, unknown fields, proto3 optional values, or several RPC transports matter. It is less suitable for projects that want schema-free TypeScript interfaces or cannot add `protoc` to their development workflow. Before adoption, verify that every required transport and server style is documented in the MANUAL, inspect generated output for your schemas, and confirm that your protobuf compiler accepts the `--experimental_allow_proto3_optional` flag if it requests that option. The repository is not archived, and its last push was on 2026-07-22.

Frequently asked questions

How do I install and run protobuf-ts?

Install `@protobuf-ts/plugin` and `protoc` as development dependencies, place the schema under `protos/`, and run `npx protoc --ts_out . --proto_path protos protos/msg-readme.proto`. The command generates `msg-readme.ts`.

Does protobuf-ts support BigInt and proto3 optional fields?

Yes. The README documents `bigint` support for 64-bit integers and shows `id: 123n`. It also lists proto3 optional support, with the note that some `protoc` versions require `--experimental_allow_proto3_optional`.

Which RPC transports does protobuf-ts generate?

The README lists generated clients for gRPC Web, Twirp, and gRPC. It also documents native gRPC servers and clients for use with `@grpc/grpc-js`.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. README
  4. Releases
  5. timostamm/protobuf-ts 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/timostamm-protobuf-ts.svg)](https://hysenlabs.com/projects/timostamm-protobuf-ts)

Was this useful?