protons
raw JSON → 8.1.1 verified Fri May 01 auth: no javascript
Protons is a high-performance Protocol Buffers v3 transpiler that converts .proto files into TypeScript. Current stable version is 8.1.1 (March 2026), with active development under the IPFS project. It differs from protobuf.js by supporting only proto3 semantics, using BigInts for 64-bit types (not Longs), representing optional unset fields as undefined, and deserializing map fields as ES6 Maps. Protons also allows limiting repeated/map element sizes for security and supports streaming decode since v8.0.0. Ships TypeScript types and requires both protons (dev) and protons-runtime (runtime) packages.
Common errors
error Cannot find module 'protons-runtime' ↓
cause protons-runtime is not installed as a runtime dependency.
fix
npm install --save protons-runtime
error TypeError: (0 , protons) is not a function ↓
cause Named import of protons instead of default import.
fix
import protons from 'protons'
error Error: Unsupported field type: int64 ↓
cause Generated code expects BigInt but received number or Long.
fix
Use BigInt for all 64-bit values: const foo = { largeNumber: BigInt('12345678901234567890') }
error SyntaxError: Unexpected token 'export' ↓
cause Protons v7+ generates ESM modules, but project uses CommonJS.
fix
Add "type": "module" to package.json or rename .ts files to .mts.
Warnings
breaking Streaming decode was added in v8.0.0, which changes the decode interface for generated code. Ensure protons-runtime is also updated to v6.0.0+. ↓
fix Update both protons and protons-runtime to latest versions: npm install protons@latest protons-runtime@latest
deprecated protons v7.x and earlier used Long.js for 64-bit types; v8+ uses BigInts exclusively. Existing code relying on Long will break. ↓
fix Migrate all 64-bit fields to BigInt. See migration guide: https://github.com/ipfs/protons#bigint-migration
gotcha Map fields are deserialized as ES6 Maps, not plain Objects. This differs from protobuf.js behavior. ↓
fix Use Map.prototype.get and Map.prototype.set instead of property access. Convert with Object.fromEntries(map) if needed.
gotcha Unset optional fields are deserialized as undefined, not default values. This can cause TypeScript strict null check errors. ↓
fix Use optional chaining or default values: decoded.field ?? 'default'
gotcha Singular fields set to default values (e.g., 0, false, '') are not serialized and are reset to default on deserialization. This diverges from protobuf.js. ↓
fix Use wrapper types (google.protobuf.BoolValue, etc.) if you need to distinguish between unset and default.
deprecated Protons supported CommonJS via require() in v6 and earlier. v7+ is ESM-only. ↓
fix Switch project to ESM or use dynamic import().
Install
npm install protons yarn add protons pnpm add protons Imports
- Foo wrong
const { Foo } = require('./foo')correctimport { Foo } from './foo.ts' - protons wrong
import { protons } from 'protons'correctimport protons from 'protons' - decode wrong
import decode from 'protons-runtime'correctimport { decode } from 'protons-runtime'
Quickstart
// 1. Install: npm install --save-dev protons && npm install --save protons-runtime
// 2. Create foo.proto:
// syntax = 'proto3';
// message Foo {
// string message = 1;
// }
// 3. Generate TypeScript:
// npx protons ./path/to/foo.proto ./path/to/foo.ts
// 4. Use in code:
import { Foo } from './foo.ts';
const foo = { message: 'hello world' };
const encoded = Foo.encode(foo);
const decoded = Foo.decode(encoded);
console.info(decoded.message); // 'hello world'