Simple gRPC javascript client example

I’m new to gRPC, EventstoreDB API and the whole configuration - gluing it makes me a headache.
Can someone please just give a very, very simple sample of working gRPC Node client, for example with “Append” method? I need something to begin with, official SDK is in TS , complex to read and understand for me, spent already few hours on it.

Could you elaborate a bit more on this? TypeScript just adds types, we don’t use classes, the API is based on functions. Also, the example in README is pure JS

Thanks for your quick reply!
Now I see that I may have been misunderstood. Syntax of NodeJS SDK is clear, readable and I get it to work with my dev env.
What I want to do is to communicate with ES without official SDK, using ‘@grpc/grpc-js’ and ‘@grpc/proto-loader’ - I plan to create Node-RED subflow which will be using gRPC nodes (which operates on .proto files).

I’m using below code:

const protoLoader = require('@grpc/proto-loader');
const grpc = require('@grpc/grpc-js');

const packageDefinition = protoLoader.loadSync("streams.proto");
const es_proto = grpc.loadPackageDefinition(packageDefinition).event_store.client.streams;

function main() {
	//const metadata = new grpc.Metadata();
	//metadata.set("authorization", Buffer.from(`Basic ${user}:${pass}`).toString("base64"));
	let client = new es_proto.Streams("", grpc.credentials.createInsecure());

	var call = client.Append(function (error, success) {
		if (error) {
		} else {

	let data = JSON.stringify({"test": "test"})

		content: {
			options: {
				stream_identifier: {
					streamName: Buffer.from("yagtak").toString("base64")
				expected_stream_revision: {
					any: {}

		content: {
			proposed_message: {
				id: {
					value: {
						string: "46412379-2379-2379-2379-160346412379"
				data: Buffer.from(data).toString("base64")



and getting error:

{ Error: 2 UNKNOWN: Exception was thrown by handler.
    at Object.callErrorFromStatus (/Users/tomek/Projects/grpc/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
    at Object.onReceiveStatus (/Users/tomek/Projects/grpc/node_modules/@grpc/grpc-js/build/src/client.js:244:52)
    at Object.onReceiveStatus (/Users/tomek/Projects/grpc/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:342:141)
    at Object.onReceiveStatus (/Users/tomek/Projects/grpc/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:305:181)
    at process.nextTick (/Users/tomek/Projects/grpc/node_modules/@grpc/grpc-js/build/src/call-stream.js:124:78)
    at process._tickCallback (internal/process/next_tick.js:61:11)
  code: 2,
  details: 'Exception was thrown by handler.',
   Metadata {
      Map {
        'date' => [Array],
        'content-type' => [Array],
        'server' => [Array],
        'content-length' => [Array],
        'grpc-encoding' => [Array] },
     options: {} } }
2020-10-23T19:06:55.331Z | call_stream | [0] HTTP/2 stream closed with code 8

which say me nothing.

I have no idea how proper request body/bodies should looks like.

You can see by yourself by looking at the code. Here’s a link where we do a write request:

We also used “@grpc/grpc-js” and went the code generation route.