gRPC for TypeScript: Libraries, Setup, and Code 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 modern high-performance Remote Procedure Call (RPC) framework developed by Google. It uses Protocol Buffers (protobuf) as its interface definition language and data serialization format. In TypeScript, gRPC is implemented using the @grpc/grpc-js package (for server and client logic) and protobufjs (for working with .proto files). In this article, we will cover the key libraries, environment setup, and write a working example in TypeScript.



Key Libraries for gRPC in TypeScript



  • @grpc/grpc-js — a pure JavaScript implementation of gRPC (no C++ addons). It supports all core features: unary calls, server and client streaming, and bidirectional streaming.
  • protobufjs — a library for loading, parsing, and generating classes from .proto files. It allows dynamic creation of messages and services.
  • @grpc/proto-loader — a helper package that simplifies loading proto files and automatically generates TypeScript types based on the definitions.
  • ts-protoc-gen — a code generator for the protoc compiler. It allows generating strictly typed classes and interfaces from .proto files.


For most projects, the combination of @grpc/grpc-js + @grpc/proto-loader is sufficient. If maximum type safety is required, use ts-protoc-gen or protobufjs with static type generation.



Installing Dependencies



Create a new project and install the necessary packages:



mkdir grpc-typescript-examplecd grpc-typescript-examplenpm init -ynpm install @grpc/grpc-js @grpc/proto-loadernpm install -D typescript @types/nodenpx tsc --init


Creating a Proto File



Let's define a simple service for working with users. Create a file user.proto:



syntax = "proto3";

package user;

service UserService { rpc GetUser (GetUserRequest) returns (User); rpc ListUsers (ListUsersRequest) returns (stream User);}

message GetUserRequest { int32 id = 1;}

message ListUsersRequest { int32 page = 1; int32 limit = 2;}

message User { int32 id = 1; string name = 2; string email = 3;}


Implementing a gRPC Server in TypeScript



Create a file server.ts:



import * as grpc from '@grpc/grpc-js';import * as protoLoader from '@grpc/proto-loader';import path from 'path';

const PROTO_PATH = path.join(__dirname, 'user.proto');

const packageDefinition = protoLoader.loadSync(PROTO_PATH, { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true,});

const userProto = grpc.loadPackageDefinition(packageDefinition) as any;

// Simulated databaseconst users = [ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' },];

function getUser( call: grpc.ServerUnaryCall<{ id: number }, any>, callback: grpc.sendUnaryData<any>) { const user = users.find(u => u.id === call.request.id); if (!user) { return callback({ code: grpc.status.NOT_FOUND, message: 'User not found', }); } callback(null, user);}

function listUsers(call: grpc.ServerWritableStream<{ page: number; limit: number }, any>) { const page = call.request.page || 1; const limit = call.request.limit || 10; const start = (page - 1) * limit; const end = start + limit; const paginatedUsers = users.slice(start, end); paginatedUsers.forEach(user => call.write(user)); call.end();}

function main() { const server = new grpc.Server();

Recommendations