@grpc/grpc-js is the official gRPC implementation for Node.js servers, enabling high-performance service-to-service communication. grpc-web is the official Google client for browsers, allowing web apps to talk to gRPC services via a proxy. @improbable-eng/grpc-web is a community-driven TypeScript client for gRPC-Web that historically offered easier integration for web developers. While all three handle gRPC protocols, they target different runtimes — server versus browser — and require distinct infrastructure setups.
Choosing the right gRPC library depends entirely on where your code runs. @grpc/grpc-js is built for Node.js servers, while grpc-web and @improbable-eng/grpc-web are designed for browsers. Mixing them up leads to build failures or runtime errors. Let's break down how they handle environment support, setup, and API design.
@grpc/grpc-js runs exclusively on Node.js.
http2 module.// @grpc/grpc-js: Server-side only
const { Client, credentials } = require('@grpc/grpc-js');
const client = new Client('localhost:50051', credentials.createInsecure());
// ❌ Will throw error if bundled for webpack/vite in browser
grpc-web runs in browsers.
// grpc-web: Browser client (generated code)
const { GreeterClient } = require('./proto/helloworld_grpc_web_pb');
const client = new GreeterClient('https://api.example.com', null, null);
// ✅ Works in browser via XHR or Fetch
@improbable-eng/grpc-web runs in browsers.
// @improbable-eng/grpc-web: Browser client
import { createClientFactory } from '@improbable-eng/grpc-web';
const client = createClientFactory().create(MyService);
// ✅ Works in browser, handles transport internally
@grpc/grpc-js uses standard protoc plugins.
grpc_tools_node_protoc_plugin.// @grpc/grpc-js: Generation command
protoc --js_out=import_style=commonjs,binary:. \
--grpc_out=grpc_js:. \
--plugin=protoc-gen-grpc=./node_modules/.bin/grpc_tools_node_protoc_plugin \
service.proto
grpc-web requires specific web plugins.
protoc-gen-grpc-web to generate compatible code.// grpc-web: Generation command
protoc --js_out=import_style=commonjs:. \
--grpc-web_out=import_style=commonjs,mode=grpcwebtext:. \
service.proto
@improbable-eng/grpc-web uses its own plugin or compatible output.
// @improbable-eng/grpc-web: Generation command
protoc --js_out=import_style=commonjs:. \
--grpc-web_out=import_style=commonjs,mode=grpcwebtext:. \
service.proto
// Then wrap with @improbable-eng/grpc-web utilities
@grpc/grpc-js leans heavily on callbacks.
// @grpc/grpc-js: Callback style
client.sayHello(request, (err, response) => {
if (err) console.error(err);
else console.log(response.message);
});
grpc-web uses callbacks in generated code.
(err, response) signatures.// grpc-web: Callback style
client.sayHello(request, { customHeader: 'value' }, (err, response) => {
if (err) console.error(err);
else console.log(response.getMessage());
});
@improbable-eng/grpc-web supports Promises natively.
// @improbable-eng/grpc-web: Promise style
const response = await client.sayHello(request, {
headers: new Headers({ customHeader: 'value' })
});
console.log(response.message);
@grpc/grpc-js connects directly to gRPC servers.
// @grpc/grpc-js: Direct connection
// Client -> Node.js Server (Port 50051)
grpc-web requires an Envoy proxy.
// grpc-web: Proxy required
// Browser -> Envoy (HTTP/1.1 or HTTP/2) -> Node.js Server
@improbable-eng/grpc-web also requires a proxy.
grpc-web.// @improbable-eng/grpc-web: Proxy required
// Browser -> Envoy -> Node.js Server
@grpc/grpc-js is actively maintained by Google.
// @grpc/grpc-js: Stable API
// Safe for long-term enterprise use
grpc-web is actively maintained by Google.
// grpc-web: Stable API
// Safe for long-term enterprise use
@improbable-eng/grpc-web is in maintenance mode.
// @improbable-eng/grpc-web: Maintenance Mode
// ⚠️ Check repository status before committing
| Feature | @grpc/grpc-js | grpc-web | @improbable-eng/grpc-web |
|---|---|---|---|
| Runtime | 🖥️ Node.js Only | 🌐 Browser | 🌐 Browser |
| Proxy Needed | ❌ No | ✅ Yes (Envoy) | ✅ Yes (Envoy) |
| API Style | 🔄 Callbacks | 🔄 Callbacks | ⚡ Promises/Async |
| TS Support | 🛠️ Good | 🛠️ Requires Config | ✅ Excellent |
| Status | ✅ Active | ✅ Active | ⚠️ Maintenance |
@grpc/grpc-js is the engine for your backend.
Use it to connect microservices within your server infrastructure. It is not an option for frontend code.
grpc-web is the standard bridge for browsers.
Use it if you want official support and long-term stability. It requires setting up a proxy, but it ensures you are following the canonical gRPC-Web spec.
@improbable-eng/grpc-web is the developer-friendly alternative.
Use it if you prioritize TypeScript experience and Promise-based APIs. However, because it is in maintenance mode, you must decide if the improved DX is worth the potential risk of slower updates in the future.
Final Thought: For new projects, pairing @grpc/grpc-js on the server with official grpc-web on the client is the safest architectural choice. If you choose @improbable-eng/grpc-web, plan for a potential migration path should support cease entirely.
Choose @grpc/grpc-js if you are building backend microservices in Node.js that need to communicate with other gRPC services. It is not suitable for browsers. This package is the standard for server-side gRPC in the JavaScript ecosystem and offers full support for streaming and metadata.
Choose @improbable-eng/grpc-web if you need a TypeScript-friendly gRPC-Web client with Promise-based APIs and cannot use the official client's generated code structure. However, note that this package is in maintenance mode, so evaluate if the trade-off in long-term support is acceptable for your project.
Choose grpc-web if you need an officially supported browser client and can configure an Envoy proxy in your infrastructure. It is the safest long-term bet for stability and compliance with the gRPC-Web standard, though it requires more initial setup for code generation.
Node 12 is recommended. The exact set of compatible Node versions can be found in the engines field of the package.json file.
npm install @grpc/grpc-js
Documentation specifically for the @grpc/grpc-js package is currently not available. However, documentation is available for the grpc package, and the two packages contain mostly the same interface. There are a few notable differences, however, and these differences are noted in the "Migrating from grpc" section below.
If you need a feature from the grpc package that is not provided by the @grpc/grpc-js, please file a feature request with that information.
This library does not directly handle .proto files. To use .proto files with this library we recommend using the @grpc/proto-loader package.
grpc@grpc/grpc-js is almost a drop-in replacement for grpc, but you may need to make a few code changes to use it:
.proto files using grpc.load, that function is not available in this library. You should instead load your .proto files using @grpc/proto-loader and load the resulting package definition objects into @grpc/grpc-js using grpc.loadPackageDefinition.grpc-tools, you should instead generate your files using the generate_package_definition option in grpc-tools, then load the object exported by the generated file into @grpc/grpc-js using grpc.loadPackageDefinition.Server#bind to bind ports, you will need to use Server#bindAsync instead.grpc but not supported in @grpc/grpc-js, you may need to adjust your code to handle the different behavior. Refer to the list of supported options below.grpc and @grpc/grpc-js.Many channel arguments supported in grpc are not supported in @grpc/grpc-js. The channel arguments supported by @grpc/grpc-js are:
grpc.ssl_target_name_overridegrpc.primary_user_agentgrpc.secondary_user_agentgrpc.default_authoritygrpc.keepalive_time_msgrpc.keepalive_timeout_msgrpc.keepalive_permit_without_callsgrpc.service_configgrpc.max_concurrent_streamsgrpc.initial_reconnect_backoff_msgrpc.max_reconnect_backoff_msgrpc.use_local_subchannel_poolgrpc.max_send_message_lengthgrpc.max_receive_message_lengthgrpc.enable_http_proxygrpc.default_compression_algorithmgrpc.enable_channelzgrpc.dns_min_time_between_resolutions_msgrpc.enable_retriesgrpc.max_connection_age_msgrpc.max_connection_age_grace_msgrpc.max_connection_idle_msgrpc.per_rpc_retry_buffer_sizegrpc.retry_buffer_sizegrpc.service_config_disable_resolutiongrpc.client_idle_timeout_msgrpc-node.max_session_memorygrpc-node.tls_enable_tracegrpc-node.retry_max_attempts_limitgrpc-node.flow_control_windowchannelOverridechannelFactoryOverrideThe public API of this library follows semantic versioning, with some caveats:
Call is only exposed due to limitations of TypeScript. It should not be considered part of the public API.grpc library is likely an error and should not be considered part of the public API.grpc.experimental namespace contains APIs that have not stabilized. Any API in that namespace may break in any minor version update.