{"id":48106,"library":"grpcity","title":"gRPCity","description":"gRPCity is a batteries-included gRPC framework for Node.js that wraps @grpc/grpc-js and @grpc/proto-loader behind an opinionated, promise-first API. Version 3.0.0, released 2023, requires Node >=18 and is actively maintained. Key differentiators vs raw @grpc/grpc-js: one loader reused across client/server, Koa-style middleware on both sides, sensible defaults for channel options and retry, built-in reflection, AbortSignal support, and runtime validation with zod. Written in TypeScript with complete type exports.","status":"active","version":"3.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/chakhsu/grpcity","tags":["javascript","grpcity","grpc.js","grpc","protobuf","microservice","framework","typescript"],"install":[{"cmd":"npm install grpcity","lang":"bash","label":"npm"},{"cmd":"yarn add grpcity","lang":"bash","label":"yarn"},{"cmd":"pnpm add grpcity","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core gRPC implementation","package":"@grpc/grpc-js","optional":false},{"reason":"Dynamic proto file loading","package":"@grpc/proto-loader","optional":false},{"reason":"Runtime option validation","package":"zod","optional":false}],"imports":[{"note":"ESM-only since v3. CommonJS require will not work.","wrong":"const { ProtoLoader } = require('grpcity')","symbol":"ProtoLoader","correct":"import { ProtoLoader } from 'grpcity'"},{"note":"Named export, not default.","wrong":"import gRPCServer from 'grpcity'","symbol":"gRPCServer","correct":"import { gRPCServer } from 'grpcity'"},{"note":"Named export. Type imports available: import type { gRPCClientOptions } from 'grpcity'","wrong":null,"symbol":"gRPCClient","correct":"import { gRPCClient } from 'grpcity'"}],"quickstart":{"code":"import { ProtoLoader, gRPCServer, gRPCClient } from 'grpcity';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { createServer } from 'node:http';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// 1. Load proto\nconst loader = new ProtoLoader({\n  location: path.join(__dirname, './'),\n  files: ['greeter.proto']\n});\n\n// 2. Define service class\nclass Greeter {\n  async sayGreet(ctx) {\n    const { message } = ctx.request;\n    return { message: `hello ${message || 'world'}` };\n  }\n}\n\n// 3. Start server\nconst server = new gRPCServer(loader, {\n  services: [{ serviceName: 'helloworld.Greeter', implementation: Greeter }]\n});\nserver.bind('0.0.0.0:50051', { useInsecure: true });\n\n// 4. Create client\nconst client = new gRPCClient(loader, {\n  address: 'localhost:50051',\n  useInsecure: true\n});\n\n// 5. Make a call\nasync function main() {\n  const response = await client.call('helloworld.Greeter', 'SayGreet', { message: 'gRPCity' });\n  console.log('Response:', response.message);\n}\n\nmain().catch(console.error);","lang":"typescript","description":"Shows full setup: proto loading, server with one service, client creation, and a unary RPC call."},"warnings":[{"fix":"Switch project to ESM (type: module in package.json) and use import syntax.","message":"gRPCity v3 dropped CommonJS support. Only ESM imports work.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Use import.meta.dirname or fileURLToPath(import.meta.url) for directory path.","message":"__dirname is not available in ESM; must derive from import.meta.url or use import.meta.dirname (Node >=20.11).","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Configure credentials with { credentials: grpc.credentials.createSsl() } for production.","message":"The useInsecure option is for development only. Production requires TLS.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Ensure method name matches proto rpc name (e.g., 'SayGreet' not 'sayGreet').","message":"Client call expects method name in PascalCase exactly as defined in proto.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"search_vec":"'18':30 '2023':27 '3.0.0':25 'abortsign':63 'across':43 'activ':33 'api':23 'batteri':6 'batteries-includ':5 'behind':17 'built':60 'built-in':59 'channel':55 'client/server':44 'complet':74 'default':53 'differenti':36 'export':76 'first':22 'framework':9,83 'grpc':8,80 'grpc.js':79 'grpc/grpc-js':14,39 'grpc/proto-loader':16 'grpciti':1,2,78 'includ':7 'javascript':77 'key':35 'koa':46 'koa-styl':45 'loader':41 'maintain':34 'microservic':82 'middlewar':48 'node':29 'node.js':11 'one':40 'opinion':19 'option':56 'promis':21 'promise-first':20 'protobuf':81 'raw':38 'reflect':62 'releas':26 'requir':28 'retri':58 'reus':42 'runtim':66 'sensibl':52 'side':51 'style':47 'support':64 'type':75 'typescript':72,84 'valid':67 'version':24 'vs':37 'wrap':13 'written':70 'zod':69","created_at":"2026-06-07T16:54:56.809272+00:00","updated_at":"2026-06-07T16:54:56.809272+00:00","problems":[{"fix":"npm install grpcity","cause":"Package not installed or wrong import path.","error":"Error: Cannot find module 'grpcity'"},{"fix":"Change project to ESM (type: module) and use import { ProtoLoader } from 'grpcity'","cause":"Using CommonJS require instead of ESM import.","error":"TypeError: grpcity.ProtoLoader is not a constructor"},{"fix":"Verify location and files in ProtoLoader options; use path.resolve for absolute paths.","cause":"Proto file location or filename mismatch.","error":"Error: ENOENT: no such file or directory, open '.../greeter.proto'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/chakhsu/grpcity","github":"https://github.com/chakhsu/grpcity","docs":null,"changelog":null,"pypi":null,"npm":"grpcity","openapi_spec":null,"status_page":null,"smithery":null,"categories":["devops"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-07","next_check":"2026-09-05","install_tag":null}}