{"id":11597,"library":"protoc-gen-ts","title":"Protocol Buffer Compiler for TypeScript","description":"protoc-gen-ts is a `protoc` plugin that generates plain TypeScript source files from Protocol Buffer `.proto` definitions, effectively replacing separate `.d.ts` declaration files. It is actively maintained, with the current stable version being `0.8.7`, and new features/fixes are delivered through frequent minor releases. A key differentiator is its direct TypeScript output which eliminates common prefixes (e.g., `getField`) and exposes fields as standard getters/setters, along with `fromObject` and `toObject` methods for robust bidirectional mapping between JSON and message instances, supporting deep structures without runtime type reflection. It offers native support for gRPC Node (`@grpc/grpc-js`) and gRPC Web, including options for promise-based RPC calls. Messages defined within a `package` directive in the `.proto` file are by default encapsulated within a TypeScript namespace, though this behavior can be toggled.","status":"active","version":"0.8.7","language":"javascript","source_language":"en","source_url":"https://github.com/thesayyn/protoc-gen-ts","tags":["javascript"],"install":[{"cmd":"npm install protoc-gen-ts","lang":"bash","label":"npm"},{"cmd":"yarn add protoc-gen-ts","lang":"bash","label":"yarn"},{"cmd":"pnpm add protoc-gen-ts","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Messages are generated as ES Modules. The path depends on your `--ts_out` setting and `package` name in your .proto file (e.g., `myproto_pb` if `package mypackage` is used, or `myproto` if no package).","wrong":"const { Change } = require('./myproto_pb');","symbol":"Change","correct":"import { Change } from './myproto_pb';"},{"note":"Enums are generated as named exports. The import path and filename reflect the proto file and package structure.","wrong":"import Kind from './myproto_pb';","symbol":"Kind","correct":"import { Kind } from './myproto_pb';"},{"note":"gRPC services generate a client class (e.g., `MyServiceClient`) and potentially an interface (e.g., `IMyService`). The exact name depends on the proto service definition.","wrong":"import { MyService } from './myproto_pb';","symbol":"MyService","correct":"import { MyServiceClient } from './myproto_pb';"}],"quickstart":{"code":"import { Change, Kind, Author } from './myproto_pb'; // Assumes protoc-gen-ts generated './myproto_pb.ts'\n\n// Construct a message instance\nconst author = new Author({\n    name: 'mary poppins',\n    role: 'maintainer'\n});\n\nconst change = new Change({\n    kind: Kind.UPDATED,\n    patch: '@@ -7,11 +7,15 @@',\n    tags: ['no prefix', 'as is'],\n    name: 'patch for typescript 4.5',\n    author: author\n});\n\n// Serialize to bytes (Uint8Array)\nconst bytes: Uint8Array = change.serialize();\n\nconsole.log('Serialized bytes:', bytes);\n\n// Deserialize from bytes back into a message instance\nconst receivedChange: Change = Change.deserialize(bytes);\n\nconsole.log('Deserialized Change object:', receivedChange);\nconsole.log('Kind:', receivedChange.kind === Kind.UPDATED); // true\nconsole.log('Author name:', receivedChange.author?.name); // mary poppins\n\n// Using fromObject for easier JSON-to-message mapping\nconst jsonChange = Change.fromObject({\n    kind: Kind.DELETED,\n    patch: 'deleted line',\n    tags: ['cleanup'],\n    id: '12345',\n    author: {\n        name: 'john doe',\n        role: 'contributor'\n    }\n});\n\nconsole.log('Change from JSON:', jsonChange.toObject());\nconsole.log('Author from JSON is an Author instance:', jsonChange.author instanceof Author);","lang":"typescript","description":"This quickstart demonstrates how to create, serialize, and deserialize a Protocol Buffer message using the generated TypeScript classes. It also illustrates the convenient `fromObject` and `toObject` methods for JSON interoperability."},"warnings":[{"fix":"Review code that checks for the presence of fields or relies on `undefined` for unset fields. Explicitly check for field presence if distinguishing between an unset field and a field with its default value is critical. For oneof fields, check the `oneof_name` property to determine which field is set.","message":"In version `0.8.5`, `getters` and `toObject` methods were changed to return the *default value* for a field if it is not present, instead of `undefined`. This affects behavior for optional fields, proto2 fields, and oneof fields that are not set, potentially requiring code adjustments if `undefined` or `null` checks were previously used.","severity":"breaking","affected_versions":">=0.8.5"},{"fix":"Consult the official `protoc-gen-ts` documentation or GitHub repository for updated Bazel integration guidelines and migration paths.","message":"The `index.bzl` file has been deprecated in version `0.8.7`. Users integrating with Bazel build systems may need to update their Bazel configurations to align with the new recommended practices for Bazel integration.","severity":"deprecated","affected_versions":">=0.8.7"},{"fix":"Use the `--ts_opt=no_namespace` option when running `protoc` to disable namespace generation and have all generated types in the global module scope (or their respective file modules).","message":"By default, `protoc-gen-ts` generates TypeScript namespaces corresponding to the `package` directive in your `.proto` files. If you prefer a flatter module structure or encounter issues with namespace resolution, this behavior can be altered.","severity":"gotcha","affected_versions":">=0.8.0"},{"fix":"Ensure `protoc-gen-ts` is installed globally (`npm install -g protoc-gen-ts`) and that its installation directory is in your system's PATH. Alternatively, you can explicitly provide the plugin path to `protoc` using `--plugin=protoc-gen-ts=/path/to/protoc-gen-ts`.","message":"`protoc-gen-ts` is a `protoc` plugin and must be discoverable by the `protoc` executable. If `protoc` cannot find the plugin, it will fail with an error indicating the program is not found.","severity":"gotcha","affected_versions":">=0.8.0"},{"fix":"If using gRPC functionality from generated code, ensure you have installed the appropriate gRPC runtime library: `npm install @grpc/grpc-js` for Node.js or include the necessary gRPC Web client libraries for browser environments.","message":"The package `protoc-gen-ts` itself does not have runtime npm dependencies beyond standard Node.js/TypeScript. However, the *generated code* often relies on runtime libraries for gRPC functionality (e.g., `@grpc/grpc-js` or `grpc`). These must be installed separately in your project if you generate gRPC service clients/servers.","severity":"gotcha","affected_versions":">=0.8.0"}],"env_vars":null,"search_vec":"'0.8.7':41 'activ':33 'along':71 'base':109 'behavior':132 'bidirect':79 'buffer':2,22 'call':111 'common':61 'compil':3 'current':37 'd.ts':28 'declar':29 'deep':87 'default':124 'defin':113 'definit':24 'deliv':46 'differenti':53 'direct':56,117 'e.g':63 'effect':25 'elimin':60 'encapsul':125 'expos':66 'features/fixes':44 'field':67 'file':19,30,121 'frequent':48 'fromobject':73 'gen':8 'generat':15 'getfield':64 'getters/setters':70 'grpc':98,102 'grpc/grpc-js':100 'includ':104 'instanc':85 'javascript':136 'json':82 'key':52 'maintain':34 'map':80 'messag':84,112 'method':76 'minor':49 'namespac':129 'nativ':95 'new':43 'node':99 'offer':94 'option':105 'output':58 'packag':116 'plain':16 'plugin':13 'prefix':62 'promis':108 'promise-bas':107 'proto':23,120 'protoc':7,12 'protoc-gen-t':6 'protocol':1,21 'reflect':92 'releas':50 'replac':26 'robust':78 'rpc':110 'runtim':90 'separ':27 'sourc':18 'stabl':38 'standard':69 'structur':88 'support':86,96 'though':130 'toggl':135 'toobject':75 'ts':9 'type':91 'typescript':5,17,57,128 'version':39 'web':103 'within':114,126 'without':89","created_at":"2026-04-19T13:38:48.858550+00:00","updated_at":"2026-04-19T13:38:48.858550+00:00","problems":[{"fix":"Install `protoc-gen-ts` globally (`npm install -g protoc-gen-ts`) and ensure your PATH includes npm's global bin directory. Alternatively, specify the full path to the plugin: `protoc --plugin=protoc-gen-ts=$(which protoc-gen-ts) -I=...`.","cause":"The `protoc` compiler cannot locate the `protoc-gen-ts` executable in the system's PATH.","error":"protoc-gen-ts: program not found"},{"fix":"Verify that the `--ts_out` option in your `protoc` command points to the correct output directory. Ensure your `tsconfig.json` includes this directory in `include` or `files`, and that `baseUrl` and `paths` are configured correctly if you are using path aliases. Adjust import statements to match the actual generated file names and paths.","cause":"The TypeScript compiler cannot resolve the import path to the generated Protocol Buffer files, either due to incorrect path, missing `tsconfig.json` configuration, or the generated files not being in the include path.","error":"TS2307: Cannot find module './myproto_pb' or its corresponding type declarations."},{"fix":"Ensure the JSON object passed to `fromObject` strictly adheres to the structure of your `.proto` message definition, especially for nested messages and repeated fields. Verify all required fields are present and correctly typed.","cause":"This typically occurs when `fromObject` is called with an invalid or unexpected JSON structure, such as a missing nested object or an array where a single object is expected, and an attempt is made to access properties on `undefined`.","error":"TypeError: Cannot read properties of undefined (reading 'name') at Object.fromObject"},{"fix":"Check your `.proto` file for the exact field name. By default, fields are named as-is. If `json_names` option is enabled, check for camelCase. For `oneof` fields, access the field through the `oneof_name` property first. Ensure your TypeScript version is compatible (e.g., `ts-5` is allowed as a peer dep since `0.8.7`).","cause":"This can happen if you are trying to access a field using a name that does not match the generated TypeScript property, or if the field is part of a `oneof` and is not currently set, or if an older version of TypeScript is used that doesn't fully support certain generated constructs.","error":"TS2339: Property 'myField' does not exist on type 'MyMessage'."}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"protoc-gen-ts","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/thesayyn/protoc-gen-ts","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/protoc-gen-ts","openapi_spec":null,"status_page":null,"smithery":null,"categories":["serialization","type-stubs"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-18","install_tag":null}}