{"id":15633,"library":"grpc-web","title":"gRPC-Web Client Runtime Library","description":"grpc-web is the JavaScript client runtime library that enables browser-based applications to communicate with gRPC services. It functions by connecting to gRPC services through a specialized gateway proxy, such as Envoy, which has built-in gRPC-Web support. The current stable version is 2.0.2, with recent releases addressing bug fixes and minor improvements, including TypeScript compatibility updates. The project maintains a steady release cadence for bug fixes and incremental features. Key differentiators include its focus on browser environments, robust TypeScript support for generated client stubs, and the reliance on `protoc` and `protoc-gen-grpc-web` for generating client code and message definitions from `.proto` files, providing a full-stack gRPC experience for web clients.","status":"active","version":"2.0.2","language":"javascript","source_language":"en","source_url":"https://github.com/grpc/grpc-web","tags":["javascript","typescript"],"install":[{"cmd":"npm install grpc-web","lang":"bash","label":"npm"},{"cmd":"yarn add grpc-web","lang":"bash","label":"yarn"},{"cmd":"pnpm add grpc-web","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This is a named import for a generated client stub. The path and name depend on your `.proto` file and `protoc-gen-grpc-web` output options. CommonJS `require` is also supported if `import_style=commonjs` was used during generation.","wrong":"const {EchoServiceClient} = require('./generated/echo_grpc_web_pb.js');","symbol":"EchoServiceClient","correct":"import {EchoServiceClient} from './generated/echo_grpc_web_pb';"},{"note":"This is a named import for a generated message type. The path and name depend on your `.proto` file and `protoc` output options. CommonJS `require` is also supported if `import_style=commonjs` was used during generation.","wrong":"const {EchoRequest} = require('./generated/echo_pb.js');","symbol":"EchoRequest","correct":"import {EchoRequest} from './generated/echo_pb';"},{"note":"The main library is imported as a namespace, commonly aliased as `grpcWeb` or `grpc`. Specific classes like `RpcError` and `Status` are accessed via this namespace (e.g., `grpcWeb.RpcError`).","wrong":"import { GrpcWebClient } from 'grpc-web';","symbol":"grpcWeb","correct":"import * as grpcWeb from 'grpc-web';"},{"note":"RpcError is typically used as a type annotation in callbacks. Introduced as an improved error type in v1.3.0.","symbol":"RpcError","correct":"import * as grpcWeb from 'grpc-web'; /* ... */ (err: grpcWeb.RpcError) => { /* ... */ }"}],"quickstart":{"code":"import * as grpcWeb from 'grpc-web';\nimport { EchoServiceClient } from './generated/echo_grpc_web_pb';\nimport { EchoRequest, EchoResponse } from './generated/echo_pb';\n\n// Ensure you have a gRPC-Web proxy (e.g., Envoy) running at this address\nconst GRPC_PROXY_ADDRESS = 'http://localhost:8080';\n\n// Create a client instance for your gRPC service\nconst echoService = new EchoServiceClient(GRPC_PROXY_ADDRESS, null, null);\n\n// Create a new request message\nconst request = new EchoRequest();\nrequest.setMessage('Hello from gRPC-Web!');\n\n// Define custom metadata (optional)\nconst metadata = { 'custom-header-1': 'value1' };\n\n// Make the gRPC call\nconst call = echoService.echo(\n  request,\n  metadata,\n  (err: grpcWeb.RpcError, response: EchoResponse) => {\n    if (err) {\n      console.error('Error during gRPC call:', err.code, err.message);\n      return;\n    }\n    console.log('Received message:', response.getMessage());\n  }\n);\n\n// Handle status updates (optional, for streaming or status monitoring)\ncall.on('status', (status: grpcWeb.Status) => {\n  if (status.code !== grpcWeb.StatusCode.OK) {\n    console.warn('gRPC call status:', status.code, status.details);\n  } else {\n    console.info('gRPC call completed successfully.');\n  }\n});\n\n// Handle stream errors (for server streaming, optional)\ncall.on('error', (err: grpcWeb.RpcError) => {\n  console.error('Stream error:', err.message);\n});","lang":"typescript","description":"This quickstart demonstrates how to instantiate a gRPC-Web client, create a request, send it to a gRPC service through a proxy, and handle the response and potential errors using TypeScript."},"warnings":[{"fix":"Upgrade `grpc-web` to version 2.0.2 or newer to ensure compatibility with TypeScript 5.9+ through the use of regular enums in generated code. Regenerate your client stubs with the latest `protoc-gen-grpc-web`.","message":"Enums generated for TypeScript versions older than 5.9 might encounter compatibility issues, leading to compilation errors or unexpected runtime behavior.","severity":"breaking","affected_versions":"<=2.0.1"},{"fix":"Ensure you have a gRPC-Web compatible proxy configured and running between your browser client and your gRPC backend. Refer to the gRPC-Web documentation for proxy setup instructions, typically using Envoy.","message":"gRPC-Web clients cannot directly connect to standard gRPC servers. An intermediary proxy (e.g., Envoy, or a gRPC-Web enabled Node.js proxy) is strictly required to translate between the gRPC-Web protocol used by browsers and the HTTP/2 gRPC protocol used by servers.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Download and install `protoc` from the official Protocol Buffers releases and `protoc-gen-grpc-web` from the gRPC-Web GitHub releases. Ensure both executables are in your system's PATH and have appropriate permissions.","message":"Generating client stubs and message definitions requires both `protoc` (Protocol Buffers compiler) and `protoc-gen-grpc-web` (gRPC-Web plugin) to be installed and accessible in your system's PATH. Incorrect versions or missing executables will lead to generation failures.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Consistently use either `import_style=commonjs+dts` or `import_style=typescript` for `protoc-gen-grpc-web`. For modern TypeScript projects, `import_style=typescript` is often preferred. Ensure your `tsconfig.json` compiler options are compatible with the chosen import style.","message":"When generating TypeScript client stubs, choosing `import_style=commonjs+dts` provides CommonJS-style JavaScript files with separate `.d.ts` declaration files, while `import_style=typescript` provides full TypeScript output. Mixing these or using an inappropriate style can lead to import errors or type mismatches.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Download `protoc-gen-grpc-web` from the GitHub releases page, place it in a directory included in your system's PATH, and ensure it has execute permissions (e.g., `chmod +x protoc-gen-grpc-web`).","cause":"The `protoc-gen-grpc-web` plugin is either not installed, not in the system's PATH, or lacks execute permissions.","error":"protoc-gen-grpc-web: program not found or is not executable"},{"fix":"Ensure `import * as grpcWeb from 'grpc-web';` is present and that your bundling tool (webpack, Parcel, Rollup) correctly includes the `grpc-web` library in your final output. Verify your `protoc-gen-grpc-web` output options match your project's module system (CommonJS/ESM).","cause":"This often indicates that the `grpc-web` runtime library is not correctly imported or bundled, or that the generated client stub is trying to access `grpc.web` properties that are not available.","error":"TypeError: Cannot read properties of undefined (reading 'ClientReadableStream')"},{"fix":"Configure your gRPC-Web proxy (e.g., Envoy's CORS filter) to include the `Access-Control-Allow-Origin` header with the appropriate value (e.g., your frontend's URL or `*` for development) and allow necessary HTTP methods (POST, OPTIONS) and headers.","cause":"The gRPC-Web proxy (e.g., Envoy) or the backend server is not correctly configured to handle Cross-Origin Resource Sharing (CORS) preflight requests from your web application's origin.","error":"CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."}],"ecosystem":"npm"}