{"id":12208,"library":"twirpscript","title":"TwirpScript","description":"TwirpScript is a Protocol Buffers (Protobuf) RPC framework designed for JavaScript and TypeScript environments. It automates the generation of both client and server code from `.proto` service definitions, facilitating type-safe communication in both browser and Node.js runtimes. The package is currently at version 0.0.72 and maintains an active release cadence with frequent minor updates addressing bug fixes and improvements. A key differentiator is its adherence to the Twirp Wire Protocol (v7) and its focus on minimizing bundle sizes, especially through tree-shaking and a lightweight runtime (2KB for TwirpScript, 37KB for the underlying ProtoScript serialization runtime). This makes it an efficient alternative to larger RPC frameworks, particularly for web applications requiring lean client bundles and strict type enforcement.","status":"active","version":"0.0.72","language":"javascript","source_language":"en","source_url":"https://github.com/tatethurston/twirpscript","tags":["javascript","protobuf","protocol buffers","rpc","twirp","typescript"],"install":[{"cmd":"npm install twirpscript","lang":"bash","label":"npm"},{"cmd":"yarn add twirpscript","lang":"bash","label":"yarn"},{"cmd":"pnpm add twirpscript","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core serialization/deserialization runtime for Protobuf messages.","package":"protoscript","optional":false}],"imports":[{"note":"TwirpScript is primarily designed for ESM; CommonJS 'require' is not recommended and may lead to issues.","wrong":"const { createTwirpClient } = require('twirpscript')","symbol":"createTwirpClient","correct":"import { createTwirpClient } from 'twirpscript'"},{"note":"This is a named export, not a default export.","wrong":"import createTwirpServer from 'twirpscript'","symbol":"createTwirpServer","correct":"import { createTwirpServer } from 'twirpscript'"},{"note":"Used for type-checking the 'proto.config.mjs' file. Available as a named export from the main package.","wrong":"import type { Config } from 'twirpscript/config'","symbol":"Config","correct":"import { Config } from 'twirpscript'"}],"quickstart":{"code":"// haberdasher.proto (example service definition)\n// syntax = \"proto3\";\n// package twirp.example;\n\n// message Hat {\n//   int32 inches = 1;\n//   string color = 2;\n//   string name = 3;\n// }\n\n// message Size {\n//   int32 inches = 1;\n// }\n\n// service Haberdasher {\n//   rpc MakeHat(Size) returns (Hat);\n// }\n\n// After running TwirpScript compiler (e.g., twirpscript --proto_path=. haberdasher.proto),\n// this would generate `haberdasher.pb.ts` and `haberdasher.twirp.ts`.\n\n// client.ts\nimport { createTwirpClient } from 'twirpscript';\nimport { Haberdasher } from './haberdasher.twirp'; // Generated Twirp service client\nimport { Size } from './haberdasher.pb'; // Generated Protobuf message type\n\nconst BASE_URL = 'http://localhost:8080/twirp'; // Replace with your Twirp server URL\n\nasync function runClient() {\n  // Create a Twirp client for the Haberdasher service\n  const client = createTwirpClient(Haberdasher, BASE_URL);\n\n  try {\n    // Define the request message for MakeHat\n    const size: Size = { inches: 12 };\n    \n    // Call the RPC method\n    const hat = await client.MakeHat(size);\n    \n    console.log(`Successfully made a hat: ${hat.name} (${hat.color}, ${hat.inches} inches)`);\n  } catch (error) {\n    console.error('Error making hat:', error);\n  }\n}\n\nrunClient();","lang":"typescript","description":"This example demonstrates how to create and use a TwirpScript client to interact with a generated Protobuf RPC service, such as a 'Haberdasher' service."},"warnings":[{"fix":"Rename your configuration file from `.twirp.json` to `proto.config.mjs` and rewrite its content as a JavaScript ES module. For example, `export default { root: \"src\" };`.","message":"The configuration file format changed from a JSON file (`.twirp.json`) to a JavaScript ES module (`proto.config.mjs`).","severity":"breaking","affected_versions":">=0.0.63"},{"fix":"Update your `buf.gen.yaml` to change the plugin path from `./node_modules/protoscript/compiler.js` to `./node_modules/protoscript/dist/compiler.js`.","message":"For users leveraging Buf, the path to the `protoc-gen-protoscript` compiler within `buf.gen.yaml` has changed.","severity":"breaking","affected_versions":">=0.0.67"},{"fix":"Ensure any server-side logic or client-side interceptors that process HTTP headers are updated to expect and handle lowercase header names.","message":"All generated HTTP header names are now consistently lowercased, affecting both `createTwirpServer` (Node.js) and `createTwirpServerless` usages.","severity":"gotcha","affected_versions":">=0.0.68"},{"fix":"While the TypeScript compiler correctly handles these imports, be aware that the runtime expects `.js` extensions. No direct code fix is typically needed, but this is an important distinction for module resolution understanding.","message":"Generated TypeScript imports for `.proto` files reverted to using `.pb` extensions instead of `.pb.js` when targeting ESM.","severity":"gotcha","affected_versions":">=0.0.64"},{"fix":"Update to version `0.0.71` or newer to ensure correct JSON serialization of Protobuf `Timestamp` and `Duration` well-known types.","message":"Fix for incorrect JSON serialization of `Timestamp` and `Duration` types when their `seconds` or `nanos` fields were zero, causing them to be omitted from the JSON output.","severity":"gotcha","affected_versions":"<=0.0.70"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Update to `twirpscript` version `0.0.72` or newer, which includes a fix for resolving the compiler path on Windows to support monorepos.","cause":"The TwirpScript compiler path could not be resolved correctly on Windows, particularly in monorepo setups.","error":"Error: Command failed with exit code 1: protoscript --compiler-path ... The system cannot find the path specified."},{"fix":"Update to `twirpscript` version `0.0.66` or newer, which includes a fix for this intermittent compilation issue.","cause":"Intermittent `EAGAIN` errors encountered during the Protobuf compilation process.","error":"Error: read EAGAIN"},{"fix":"For Buf users, update the plugin path in your `buf.gen.yaml` from `./node_modules/protoscript/compiler.js` to `./node_modules/protoscript/dist/compiler.js` (applicable for versions `v0.0.67` and newer).","cause":"The path specified in `buf.gen.yaml` for the `protoc-gen-protoscript` plugin is incorrect or outdated.","error":"Cannot find module 'protoscript/compiler.js' from '.../buf.gen.yaml'"}],"ecosystem":"npm"}