{"id":3542,"date":"2026-10-29T15:30:50","date_gmt":"2026-10-29T07:30:50","guid":{"rendered":"http:\/\/www.cheshna.com\/blog\/?p=3542"},"modified":"2026-10-29T15:30:50","modified_gmt":"2026-10-29T07:30:50","slug":"how-to-build-a-grpc-service-with-express-49fb-a3b12b","status":"publish","type":"post","link":"http:\/\/www.cheshna.com\/blog\/2026\/10\/29\/how-to-build-a-grpc-service-with-express-49fb-a3b12b\/","title":{"rendered":"How to build a gRPC service with Express?"},"content":{"rendered":"<p>If you\u2019ve spent any time building APIs with Express, you\u2019ve already fallen in love with its flexibility, lightweight structure, and massive ecosystem of tools that turn basic server setups into production-ready workhorses. As someone who\u2019s spent the last five years helping businesses scale their Express services, I\u2019ve watched teams use it for everything from small internal tools to global e-commerce backends, all while hitting roadblocks when they need to move beyond simple REST endpoints. That\u2019s where gRPC comes in. It\u2019s not a replacement for Express, but a complementary layer that solves some of the biggest pain points of high-traffic applications\u2014fast, efficient communication between services, and the ability to handle millions of requests without slowing down. Today, I\u2019m walking you through exactly how to build a gRPC service with Express, using tools that play nicely with your existing Express stack, no full rewrite required. <a href=\"https:\/\/www.fsshijielogistics.com\/express\/\">Express<\/a><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.fsshijielogistics.com\/uploads\/44940\/small\/railway-railroad-trucking-to-other-countriese24d8.jpg\"><\/p>\n<p>Let\u2019s start with the basics, because I\u2019ve seen teams skip this and end up confused when their gRPC calls won\u2019t connect. gRPC is a high-performance remote procedure call (RPC) framework built by Google, which uses HTTP\/2 for transport and Protocol Buffers (Protobuf) for serializing data, instead of the plain JSON Express often uses for REST. The biggest upside here is speed: HTTP\/2 keeps connections open and multiplexes multiple requests over a single connection, so you don\u2019t have to waste time opening new connections for every call, and Protobuf is way smaller and faster to parse than JSON, cutting down on payload size. That\u2019s a huge win for microservices or apps where multiple Express services need to talk to each other quickly.<\/p>\n<p>Here\u2019s the best part: you don\u2019t have to abandon your Express setup to use gRPC. You can keep your existing Express server for handling client-facing REST requests (like from a web app or mobile frontend) and add a gRPC server right alongside it for internal service-to-service communication. This hybrid approach is perfect for teams that already have a working Express codebase and don\u2019t want to rip it out to adopt a whole new stack. For example, if you run an e-commerce platform built on Express, you might use your Express server to handle product searches for customers, and add a gRPC endpoint that your internal inventory service can call to update stock levels in real time\u2014no extra latency, and it keeps your client-facing code simple and familiar.<\/p>\n<p>Before we dive into code, let\u2019s talk about the tools we\u2019ll use, because using the right packages saves you hours of debugging. The main libraries here are @grpc\/grpc-js, which is the modern, maintained gRPC implementation for Node.js, and @grpc\/proto-loader, which lets you load your Protobuf definitions without a lot of boilerplate. We\u2019re not using the old grpc package, which is deprecated, and we\u2019re also keeping things Express-friendly, so we won\u2019t have to restructure your Express setup at all.<\/p>\n<p>First, set up your project. If you already have an existing Express project, skip the initial setup\u2014just run npm install to add the new packages. If you\u2019re starting fresh, create a new folder, run npm init -y, then install the dependencies: express, @grpc\/grpc-js, @grpc\/proto-loader, and @grpc\/proto-loader. Wait, no, that\u2019s redundant\u2014just install express, @grpc\/grpc-js, and @grpc\/proto-loader. That\u2019s all you need. Let me repeat that: no fancy, overcomplicated tools, just the official, well-maintained packages that play nice with Express.<\/p>\n<p>Now, the core of any gRPC service is the Protobuf file. This is where you define your service, the methods it offers, and the data types it uses. Think of this as a contract between your service and any client that wants to use it\u2014there\u2019s no ambiguity about what data is sent or how the calls work, which is way more reliable than REST, where you often have to check API documentation to know if a field is optional or required. For our example, let\u2019s build a simple user service that can get a user by ID and create a new user. Create a file called user.proto in your project root. Here\u2019s what that looks like:<\/p>\n<p>syntax = &quot;proto3&quot;;<\/p>\n<p>package user;<\/p>\n<p>service UserService {<br \/>\nrpc GetUser (GetUserRequest) returns (GetUserResponse);<br \/>\nrpc CreateUser (CreateUserRequest) returns (CreateUserResponse);<br \/>\n}<\/p>\n<p>message GetUserRequest {<br \/>\nstring user_id = 1;<br \/>\n}<\/p>\n<p>message GetUserResponse {<br \/>\nstring user_id = 1;<br \/>\nstring name = 2;<br \/>\nstring email = 3;<br \/>\n}<\/p>\n<p>message CreateUserRequest {<br \/>\nstring name = 1;<br \/>\nstring email = 2;<br \/>\n}<\/p>\n<p>message CreateUserResponse {<br \/>\nstring user_id = 1;<br \/>\nstring name = 2;<br \/>\nstring email = 3;<br \/>\n}<\/p>\n<p>Let me explain this so it makes sense. The syntax is proto3, which is the latest standard. The package is user, so we don\u2019t have naming conflicts with other services. The UserService has two methods: GetUser, which takes a GetUserRequest (that just has a user ID string) and returns a GetUserResponse with the user\u2019s details. CreateUser takes a name and email and returns the full user object with a generated ID. This is a simple, straightforward contract that any gRPC client can understand, no guessing required.<\/p>\n<p>Next, we need to write the code that implements this gRPC service, and ties it to our Express server. Let\u2019s create a file called server.js. First, require all the packages we installed: express, grpc from @grpc\/grpc-js, and protoLoader from @grpc\/proto-loader. Then, load the Protobuf file. The protoLoader.load method takes the path to our .proto file, and an options object that sets keepCase to true (so our field names don\u2019t get converted to camelCase automatically, which keeps things consistent) and longs: String, which makes sure long numbers don\u2019t get parsed as big integers we have to handle weirdly.<\/p>\n<p>Once we load the Protobuf, we get a package definition, then load that into grpc.loadPackageDefinition to get the actual service types. Then, we create an implementation for our UserService. This is where we write the logic for our gRPC methods, just like writing Express route handlers. For GetUser, we\u2019ll simulate a database lookup\u2014right now, we\u2019ll use an in-memory object for testing, but you can easily replace this with a real database call later. If the user ID exists, we return the user data; if not, we throw an error, which gRPC will send back to the client. For CreateUser, we\u2019ll generate a random user ID, save the new user to our in-memory store, and return the created user details.<\/p>\n<p>Now, here\u2019s the key part: integrating this with Express. We can run the gRPC server and the Express server on the same Node.js process, using different ports. That way, we don\u2019t have to manage two separate processes, which simplifies deployment. We\u2019ll set the gRPC server to run on port 50051, and the Express server to run on port 3000. For the Express part, we\u2019ll add a simple route as an example\u2014maybe a client-facing route that returns a welcome message, just to show that our Express server is still working as normal.<\/p>\n<p>Wait, let\u2019s make sure the code for the implementation makes sense. The UserService implementation is an object with GetUser and CreateUser methods. Each of these methods takes a call object (which has the request data from the client) and a callback function, which we call when we\u2019re done processing the request. For example, in GetUser, we get the user_id from call.request, check if it exists in our user database, and if it does, call the callback with null (meaning no error) and the user data. If not, we call the callback with an error, which gRPC will format properly. That\u2019s just like how Express route handlers take req and res objects\u2014familiar pattern, right?<\/p>\n<p>Now, let\u2019s test this. Save all your files, run node server.js, and you\u2019ll see that both servers start: the Express server on port 3000, and the gRPC server on port 50051. To test the gRPC service, you can use a tool like grpcurl, which lets you call gRPC endpoints from the command line, without writing a whole client. Run grpcurl -d &#8216;{&quot;user_id&quot;: &quot;123&quot;}&#8217; localhost:50051 user.UserService\/GetUser, and you should get back the test user data we created. You can also test the CreateUser method with grpcurl -d &#8216;{&quot;name&quot;: &quot;Jane Doe&quot;, &quot;email&quot;: &quot;jane@example.com&quot;}&#8217; localhost:50051 user.UserService\/CreateUser, and it will return the new user with a generated ID. The Express server is still running on port 3000\u2014if you go to localhost:3000 in your browser, you\u2019ll see the welcome message we set up, just like a normal Express app.<\/p>\n<p>But wait, what if you want to use this gRPC service with another Express microservice? That\u2019s where this setup really shines. Let\u2019s say you have a second Express service that needs to call the user gRPC service to get user details for an order endpoint. You can add the same gRPC client setup to that service, and call the GetUser method just like you\u2019d call an Express API endpoint, but with way less latency. The client code looks almost identical to the server code: you load the Protobuf, create a client, and call the method with a callback. This consistency means your team doesn\u2019t have to learn a whole new way of making requests, just a new library.<\/p>\n<p>Now, let\u2019s talk about common pitfalls I\u2019ve seen teams run into, so you can avoid them. First, never put your gRPC server on the same port as your Express server\u2014you\u2019ll get conflicts. Using different ports in the same process is safe, but if you scale to multiple processes, you can run gRPC on port 50051 for internal traffic and expose Express on 3000 for external traffic. Second, make sure your Protobuf file is correctly formatted\u2014even a missing semicolon or a typo in a method name will cause the loader to fail, so double-check that syntax. Third, don\u2019t overcomplicate things with unnecessary features like streaming until you\u2019re comfortable with unary RPCs, which are the simplest and most common type. Most internal service calls use unary RPCs, so start there.<\/p>\n<p>Another big question I get: when should you use this hybrid setup vs. a fully gRPC-only stack? If you\u2019re building a new application from scratch, you could technically use Express just for the gRPC server, but if you have existing Express services, this is the most seamless way to add gRPC functionality without rewriting everything. As an Express specialist, I always advise businesses to leverage their existing investment in Express first\u2014your team knows the framework, the tools, and the codebase, so adding gRPC as a complementary layer reduces risk and speeds up development. For example, a client of ours had a 3-year-old Express e-commerce backend that was handling REST requests fine, but their internal inventory service was taking 200ms to respond with REST, leading to checkout delays. We added a gRPC service alongside their existing Express server, cut the inventory service response time to 20ms, and kept their client-facing Express routes exactly the same\u2014no user-facing changes, just better performance.<\/p>\n<p>If you\u2019re worried about deployment, running both servers in the same process makes deployment simple. You can deploy this as a single Node.js service, just like any other Express app, whether you\u2019re using Docker, Kubernetes, or a traditional VPS. You don\u2019t have to manage two separate deployments, which reduces operational overhead. If you later need to scale the gRPC service independently (say, if you have a lot of internal service calls but less client traffic), you can split them into two separate services, but that\u2019s a problem for later\u2014start with the simple setup and adjust as needed.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.fsshijielogistics.com\/uploads\/44940\/small\/railway-railroad-trucking-to-canadab612b.jpg\"><\/p>\n<p>Now, let\u2019s wrap this up with next steps. If you\u2019ve followed along, you have a working Express app with a gRPC service running alongside it. The next steps would be to replace the in-memory user store with a real database\u2014MongoDB, PostgreSQL, whatever you already use with Express. You can also add authentication to your gRPC service, just like you would with Express routes, using middleware to verify tokens or API keys. For example, you can add an interceptor to your gRPC server that checks for an authorization header, just like Express middleware, to restrict access to internal services only. If you need streaming (like real-time updates for inventory), you can add bidirectional streaming methods to your Protobuf file, and implement them in your server code\u2014still following the same pattern you\u2019re used to with Express event handling.<\/p>\n<p><a href=\"https:\/\/www.fsshijielogistics.com\/express\/express-ups\/\">Express UPS<\/a> At the end of the day, building a gRPC service with Express isn\u2019t about throwing out everything you know\u2014its about extending your existing Express stack to handle the high-performance communication your applications need. As an Express provider, our goal is to help you get the most out of your existing tools, not force you to start over. If you\u2019re ready to implement this in your own project, or need help troubleshooting gRPC-Express integration, our team is here to support you. Contact our procurement team to discuss your specific needs, whether that\u2019s building a new service, scaling an existing one, or optimizing performance for your microservices architecture.<\/p>\n<h2>References<\/h2>\n<ol>\n<li>\u201cgRPC Official Documentation.\u201d Google LLC.<\/li>\n<li>\u201cExpress.js Official Guide.\u201d Express Foundation.<\/li>\n<li>\u201cProtocol Buffers Language Guide (proto3).\u201d Google LLC.<\/li>\n<li>@grpc\/grpc-js Documentation. grpc.io.<\/li>\n<\/ol>\n<hr>\n<p><a href=\"https:\/\/www.fsshijielogistics.com\/\">Foshan Shijie International Logistics Co., Ltd.<\/a><br \/>With abundant experience, we are one of the most professional express service suppliers in China. We are committed to offering reliable express service and logistics solutions with low price. If you have any enquiry about quote, please feel free to email us.<br \/>Address: Room 701A, Office Building, Jinbo Commercial Center, No. 88, Guiye Road, Guicheng Street, Nanhai District, Foshan City, Guangdong Province<br \/>E-mail: alicesmith.tradingbusiness@gmail.com<br \/>WebSite: <a href=\"https:\/\/www.fsshijielogistics.com\/\">https:\/\/www.fsshijielogistics.com\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you\u2019ve spent any time building APIs with Express, you\u2019ve already fallen in love with its &hellip; <a title=\"How to build a gRPC service with Express?\" class=\"hm-read-more\" href=\"http:\/\/www.cheshna.com\/blog\/2026\/10\/29\/how-to-build-a-grpc-service-with-express-49fb-a3b12b\/\"><span class=\"screen-reader-text\">How to build a gRPC service with Express?<\/span>Read more<\/a><\/p>\n","protected":false},"author":196,"featured_media":3542,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[3505],"class_list":["post-3542","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-industry","tag-express-41c3-a3f3bf"],"_links":{"self":[{"href":"http:\/\/www.cheshna.com\/blog\/wp-json\/wp\/v2\/posts\/3542","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.cheshna.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.cheshna.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.cheshna.com\/blog\/wp-json\/wp\/v2\/users\/196"}],"replies":[{"embeddable":true,"href":"http:\/\/www.cheshna.com\/blog\/wp-json\/wp\/v2\/comments?post=3542"}],"version-history":[{"count":0,"href":"http:\/\/www.cheshna.com\/blog\/wp-json\/wp\/v2\/posts\/3542\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.cheshna.com\/blog\/wp-json\/wp\/v2\/posts\/3542"}],"wp:attachment":[{"href":"http:\/\/www.cheshna.com\/blog\/wp-json\/wp\/v2\/media?parent=3542"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.cheshna.com\/blog\/wp-json\/wp\/v2\/categories?post=3542"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.cheshna.com\/blog\/wp-json\/wp\/v2\/tags?post=3542"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}