Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
addReflection
✓ import { addReflection } from 'grpc-server-reflection'
✗ const { addReflection } = require('grpc-server-reflection')
This package primarily targets ESM environments for modern Node.js development. For CommonJS, require syntax is generally `const { addReflection } = require('grpc-server-reflection');`
Server
✓ import * as grpc from '@grpc/grpc-js'; const server = new grpc.Server()
✗ const { Server } = require('@grpc/grpc-js');
While named imports for `Server` might work in some CJS transpiled environments, the standard CJS pattern for `@grpc/grpc-js` is to import the entire module and access `Server` as a property. For ESM, named imports are typically used for specific symbols like `ServerUnaryCall` but `Server` itself is often accessed via a wildcard import.
ServerUnaryCall
✓ import { ServerUnaryCall } from '@grpc/grpc-js'
✗ const ServerUnaryCall = require('@grpc/grpc-js').ServerUnaryCall
TypeScript users will often import types like `ServerUnaryCall` directly for type safety in service implementations.
This quickstart demonstrates how to initialize a gRPC server with a placeholder service and then integrate `grpc-server-reflection` using a pre-generated descriptor set, enabling clients to introspect the server's capabilities.
import * as grpc from '@grpc/grpc-js';
import { addReflection } from 'grpc-server-reflection';
import * as path from 'path';
import * as fs from 'fs';
// --- Placeholder for your proto definition ---
// syntax = "proto3";
// package myapp;
// service Greeter {
// rpc SayHello (HelloRequest) returns (HelloReply) {}
// }
// message HelloRequest { string name = 1; }
// message HelloReply { string message = 1; }
// ------------------------------------------
// Dummy service implementation
const greeterService = {
SayHello: (call: grpc.ServerUnaryCall<any, any>, callback: grpc.sendUnaryData<any>) => {
const name = call.request.name || 'World';
callback(null, { message: `Hello, ${name}!` });
},
};
// Resolve paths for descriptor set
const DESCRIPTOR_SET_PATH = path.resolve(__dirname, 'descriptor_set.bin');
// In a real application, you must generate descriptor_set.bin using grpc_tools_node_protoc:
// grpc_tools_node_protoc --descriptor_set_out=${DESCRIPTOR_SET_PATH} --include_imports your_protos/**/*.proto
if (!fs.existsSync(DESCRIPTOR_SET_PATH)) {
console.warn(`
WARNING: Descriptor set file not found at ${DESCRIPTOR_SET_PATH}.
Reflection will not function without it. Please generate it.
Example command:
grpc_tools_node_protoc --descriptor_set_out=${DESCRIPTOR_SET_PATH} --include_imports --proto_path=./path/to/protos ./path/to/protos/*.proto
`);
// For quickstart to be runnable without actual proto generation, create a dummy file.
// In production, this file *must* be correctly generated.
fs.writeFileSync(DESCRIPTOR_SET_PATH, Buffer.from('DUMMY_DESCRIPTOR_SET'));
}
const server = new grpc.Server();
// Register your actual gRPC services
server.addService({
// This is a minimal representation; real services use generated types.
SayHello: {
path: '/myapp.Greeter/SayHello',
requestStream: false,
responseStream: false,
requestSerialize: (value: any) => Buffer.from(JSON.stringify(value)),
requestDeserialize: (buffer: Buffer) => JSON.parse(buffer.toString()),
responseSerialize: (value: any) => Buffer.from(JSON.stringify(value)),
responseDeserialize: (buffer: Buffer) => JSON.parse(buffer.toString()),
},
}, greeterService);
// Add gRPC server reflection to the server instance
addReflection(server, DESCRIPTOR_SET_PATH);
const port = '0.0.0.0:50051';
server.bindAsync(port, grpc.ServerCredentials.createInsecure(), (err, boundPort) => {
if (err) {
console.error(`Server bind failed on ${port}: ${err.message}`);
} else {
server.start();
console.log(`gRPC server listening on ${boundPort} with reflection enabled.`);
}
});
Errors
Common errors & fixes
Error: Failed to load descriptor set from path/to/descriptor_set.bin
The binary descriptor set file specified in `addReflection` does not exist or is not accessible.
fixVerify that `path/to/descriptor_set.bin` is the correct and absolute path to your generated descriptor set file and that the Node.js process has read permissions for it. Ensure the file was generated by `grpc_tools_node_protoc`.
gRPC reflection client fails to discover methods/services, or reports 'No such method' errors.
The descriptor set was generated without `--include_imports`, leading to an incomplete view of the service definitions, especially for services that import other proto files.
fixRe-run `grpc_tools_node_protoc` to generate your `descriptor_set.bin` file, explicitly adding the `--include_imports` flag, e.g., `grpc_tools_node_protoc --descriptor_set_out=output.bin --include_imports your_protos/**/*.proto`.
TypeError: addReflection is not a function
This typically occurs when mixing CommonJS `require()` with an ESM-only package or when using incorrect destructuring with `require()`.
fixFor ESM projects, use `import { addReflection } from 'grpc-server-reflection'`. For CommonJS, if the package explicitly supports it, use `const { addReflection } = require('grpc-server-reflection');`. Ensure your `package.json` `type` field is correctly set to `module` for ESM, or use a bundler that handles CJS/ESM interop. Audit
Dependencies
@grpc/grpc-jsrequiredCore gRPC library for Node.js servers that this package integrates with for reflection functionality.
grpcoptionalSupports the older gRPC Node.js library for server reflection as well.