gRPC for TypeScript: Libraries and Usage Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

gRPC for TypeScript: Libraries and Examples



gRPC is a high-performance RPC framework from Google that runs over HTTP/2 and uses Protocol Buffers (protobuf) for data serialization. In TypeScript (and Node.js), gRPC allows you to build efficient microservice architectures with support for streams and bidirectional communication. On this page, we will cover the main libraries, setting up the development environment, and write a working client-server application example.



Main Libraries for gRPC in TypeScript



There are three key packages for working with gRPC in the TypeScript ecosystem:



  • @grpc/grpc-js — a pure JavaScript implementation of gRPC (no native dependencies), fully supports HTTP/2 and works with Node.js 12+.
  • @grpc/proto-loader — a loader for .proto files that dynamically creates JavaScript classes based on protobuf definitions.
  • ts-proto — a TypeScript type generator from proto files. An alternative to the built-in grpc-tools, but with better support for strict typing.


Install all components with one command:



npm install @grpc/grpc-js @grpc/proto-loader ts-protonpm install -D typescript @types/node


Creating a .proto File



Let's start by defining the service. Create a file hello.proto:



syntax = "proto3";

package hello;

service Greeter { rpc SayHello (HelloRequest) returns (HelloReply); rpc SayHelloStream (HelloRequest) returns (stream HelloReply);}

message HelloRequest { string name = 1;}

message HelloReply { string message = 1;}


Generating TypeScript Types with ts-proto



ts-proto creates full-fledged interfaces and message classes. Install protoc and the plugin:



npm install -g protoc-gen-ts-protoprotoc --ts_proto_out=./generated hello.proto


As a result, you will get a file generated/hello.ts with the HelloRequest, HelloReply interfaces and a typed GreeterClient service.



Server Side (gRPC Server in TypeScript)



Create a file server.ts:



import * as grpc from '@grpc/grpc-js';import * as protoLoader from '@grpc/proto-loader';import { ProtoGrpcType } from './generated/hello';

const packageDef = protoLoader.loadSync('hello.proto');const grpcObj = (grpc.loadPackageDefinition(packageDef) as unknown) as ProtoGrpcType;const server = new grpc.Server();

server.addService(grpcObj.hello.Greeter.service, { SayHello: (call: any, callback: any) => { const name = call.request.name; callback(null, { message: `Hello, ${name}!` }); }, SayHelloStream: (call: any) => { const name = call.request.name; for (let i = 0; i < 5; i++) { call.write({ message: `Message ${i + 1} for ${name}` }); } call.end(); }});

server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => { console.log('Server started on port 50051');});


Client Side (gRPC Client in TypeScript)



Create a file client.ts:



import * as grpc from '@grpc/grpc-js';import * as protoLoader from '@grpc/proto-loader';import { ProtoGrpcType } from './generated/hello';

const packageDef = protoLoader.loadSync('hello.proto');const grpcObj = (grpc.loadPackageDefinition(packageDef) as unknown) as ProtoGrpcType;

const client = new grpcObj.hello.Greeter( 'localhost:50051', grpc.credentials.createInsecure());

// Unary callclient.SayHello({ name: 'Alice' }, (err, response) => { if (!err) console.log('Response:', response?.message);});

// Server-streaming callconst stream = client.SayHelloStream({ name: 'Bob' });stream.on('data', (data) => console.log('Stream:', data.message));stream.on('end', (

Recommendations