{"id":17834,"library":"nice-grpc-client-middleware-devtools","title":"nice-grpc DevTools Client Middleware","description":"This package provides a client-side middleware for `nice-grpc` and `nice-grpc-web` that integrates with the `grpc-web-devtools` browser extension. Its primary function is to log gRPC-Web requests and responses, making them visible and inspectable within the browser's developer tools. This is crucial for debugging frontend applications that communicate with gRPC backends via gRPC-Web, a common pain point due to gRPC-Web's protocol translation layer. Currently at version 1.0.10, the package generally follows the active development and release cadence of its parent `nice-grpc` project, which sees frequent updates. It offers a straightforward way to gain visibility into gRPC-Web traffic, differentiating itself by specifically targeting the popular `grpc-web-devtools` extension for an enhanced developer experience.","status":"active","version":"1.0.10","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","typescript"],"install":[{"cmd":"npm install nice-grpc-client-middleware-devtools","lang":"bash","label":"npm"},{"cmd":"yarn add nice-grpc-client-middleware-devtools","lang":"bash","label":"yarn"},{"cmd":"pnpm add nice-grpc-client-middleware-devtools","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"This middleware is specifically designed to work with gRPC-Web clients and the `grpc-web-devtools` browser extension.","package":"nice-grpc-web","optional":false},{"reason":"While primarily for web, `nice-grpc` is the foundational library for the ecosystem. The middleware expects a `nice-grpc` compatible client factory.","package":"nice-grpc","optional":false},{"reason":"Provides common types and utilities shared across the `nice-grpc` ecosystem.","package":"nice-grpc-common","optional":false}],"imports":[{"note":"The `nice-grpc` ecosystem is primarily ESM-first and TypeScript-centric. While CommonJS might technically work with transpilation, direct `require` is not the idiomatic approach.","wrong":"const { devtoolsClientMiddleware } = require('nice-grpc-client-middleware-devtools');","symbol":"devtoolsClientMiddleware","correct":"import { devtoolsClientMiddleware } from 'nice-grpc-client-middleware-devtools';"},{"note":"Use this specific middleware if you only want to log unary (request-response) gRPC calls to devtools, excluding streaming calls.","symbol":"devtoolsUnaryLoggingMiddleware","correct":"import { devtoolsUnaryLoggingMiddleware } from 'nice-grpc-client-middleware-devtools';"},{"note":"Use this specific middleware if you only want to log streaming gRPC calls to devtools, excluding unary calls.","symbol":"devtoolsStreamLoggingMiddleware","correct":"import { devtoolsStreamLoggingMiddleware } from 'nice-grpc-client-middleware-devtools';"}],"quickstart":{"code":"import { createClientFactory, createChannel, ClientError, Status } from 'nice-grpc-web';\nimport { devtoolsClientMiddleware } from 'nice-grpc-client-middleware-devtools';\nimport { type ExampleServiceDefinition, ExampleServiceDefinition } from './compiled_proto/example';\n\n// Imagine your compiled Protobuf types look like this (e.g., from ts-proto)\ninterface ExampleServiceDefinition {\n  readonly methodName: string;\n  readonly requestType: any;\n  readonly responseType: any;\n  // ... other protobuf definitions\n}\n\n// 1. Define your gRPC service (usually compiled from .proto)\n// ExampleServiceDefinition would come from your proto compilation output\n\n// 2. Create a gRPC-Web channel pointing to your proxy/server\nconst channel = createChannel('http://localhost:8080');\n\n// 3. Create a client factory and apply the devtools middleware\nconst clientFactory = createClientFactory()\n  .use(devtoolsClientMiddleware);\n\n// 4. Create your gRPC client instance\nconst client = clientFactory.create(\n  ExampleServiceDefinition,\n  channel,\n);\n\n// 5. Make a gRPC call (this will now be logged in grpc-web-devtools)\nasync function callService() {\n  try {\n    console.log('Making a gRPC call...');\n    const response = await client.exampleMethod({ name: 'World' }, {\n      metadata: { 'x-request-id': '123' },\n      // Additional call options can be passed here\n    });\n    console.log('gRPC response:', response);\n  } catch (error: unknown) {\n    if (error instanceof ClientError) {\n      console.error(`gRPC Error: ${error.code} - ${error.details}`);\n    } else {\n      console.error('Unknown error:', error);\n    }\n  }\n}\n\ncallService();\n\n// A minimal example for ExampleServiceDefinition if not using ts-proto directly:\nexport const ExampleServiceDefinition = {\n  methodName: 'ExampleService',\n  requestType: {}, // Define your request type structure\n  responseType: {}, // Define your response type structure\n  // Typically, this comes from compiled .proto files\n  methods: {\n    exampleMethod: {},\n  }\n} as unknown as ExampleServiceDefinition;\n","lang":"typescript","description":"This quickstart demonstrates how to integrate `devtoolsClientMiddleware` into a `nice-grpc-web` client, enabling automatic logging of gRPC-Web requests and responses to the `grpc-web-devtools` browser extension for debugging."},"warnings":[{"fix":"Ensure the `grpc-web-devtools` Chrome/Edge extension (or equivalent) is installed in your browser.","message":"This middleware is designed to work with the `grpc-web-devtools` browser extension. Requests will not appear in browser DevTools unless the extension is installed and active.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Arrange your `.use()` calls based on the desired execution order. If `devtoolsClientMiddleware` needs to see the final request/response before other transformations, place it earlier in the chain. If it needs to see them after transformations, place it later.","message":"The `nice-grpc` middleware chain processes in reverse order of attachment: `clientFactory.use(middleware1).use(middleware2)` means `middleware1` is invoked last, and `middleware2` is invoked first. Consider middleware order carefully if you have multiple middlewares.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure you are using `createClientFactory` and `createChannel` from `nice-grpc-web` when targeting browser environments for `grpc-web-devtools` integration.","message":"This middleware is primarily intended for `nice-grpc-web` clients running in the browser. While technically usable with `nice-grpc` in Node.js, it won't provide benefits for browser-based debugging there and might lead to confusion.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Use ESM `import` statements: `import { devtoolsClientMiddleware } from 'nice-grpc-client-middleware-devtools';`","cause":"Attempting to use CommonJS `require()` syntax in an ESM-only or ESM-configured project.","error":"ReferenceError: require is not defined"},{"fix":"Ensure you correctly import `createClientFactory` from `nice-grpc-web` and call `createClientFactory()` before chaining `.use()` calls: `const clientFactory = createClientFactory().use(middleware);`","cause":"Likely attempting to call `.use()` on something other than a `ClientFactory` or an incorrectly initialized factory.","error":"TypeError: Cannot read properties of undefined (reading 'use')"},{"fix":"Verify the `grpc-web-devtools` extension is installed and enabled. Double-check that `devtoolsClientMiddleware` is applied to your `createClientFactory()` instance. Ensure your browser is indeed making gRPC-Web requests (often visible as POST requests to `/Service/Method` with `Content-Type: application/grpc-web+proto` or `application/grpc-web-text`).","cause":"The `grpc-web-devtools` browser extension is not installed, not enabled, or the middleware is not correctly applied to the client factory. Also, ensure your gRPC-Web proxy (e.g., Envoy) is correctly configured.","error":"gRPC-Web calls not appearing in browser's Network tab or grpc-web-devtools extension."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}