{"id":13510321,"url":"https://github.com/mapbox/pbf","last_synced_at":"2025-10-16T02:15:54.846Z","repository":{"id":13232932,"uuid":"15917514","full_name":"mapbox/pbf","owner":"mapbox","description":"A low-level, lightweight protocol buffers implementation in JavaScript.","archived":false,"fork":false,"pushed_at":"2024-08-21T14:45:18.000Z","size":584,"stargazers_count":826,"open_issues_count":14,"forks_count":110,"subscribers_count":143,"default_branch":"main","last_synced_at":"2025-05-08T23:53:19.031Z","etag":null,"topics":["binary","decoding","encoding","fast","format","javascript","library","pbf","protocol-buffers","serialization"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mapbox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-01-14T22:22:23.000Z","updated_at":"2025-05-07T03:09:52.000Z","dependencies_parsed_at":"2024-11-01T10:31:52.581Z","dependency_job_id":"088f4265-17bb-44d9-ac57-ae8155f9f59a","html_url":"https://github.com/mapbox/pbf","commit_stats":{"total_commits":235,"total_committers":18,"mean_commits":"13.055555555555555","dds":0.225531914893617,"last_synced_commit":"bfaaa5daea7e2a57e5e0b22cca75037113000e33"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapbox%2Fpbf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapbox%2Fpbf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapbox%2Fpbf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapbox%2Fpbf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mapbox","download_url":"https://codeload.github.com/mapbox/pbf/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254133312,"owners_count":22020313,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binary","decoding","encoding","fast","format","javascript","library","pbf","protocol-buffers","serialization"],"created_at":"2024-08-01T02:01:33.742Z","updated_at":"2025-10-16T02:15:54.798Z","avatar_url":"https://github.com/mapbox.png","language":"JavaScript","readme":"# pbf\n\n[![Node](https://github.com/mapbox/pbf/actions/workflows/node.yml/badge.svg)](https://github.com/mapbox/pbf/actions/workflows/node.yml)\n![Bundle size](https://img.shields.io/bundlephobia/minzip/pbf)\n\nA low-level, fast, ultra-lightweight (3KB gzipped) JavaScript library for decoding and encoding [protocol buffers](https://developers.google.com/protocol-buffers), a compact binary format for structured data serialization. Works both in Node and the browser. Supports lazy decoding and detailed customization of the reading/writing code.\n\n## Performance\n\nThis library is extremely fast — much faster than native `JSON.parse`/`JSON.stringify`\nand the [protocol-buffers](https://github.com/mafintosh/protocol-buffers) module.\nHere's a result from running a real-world benchmark on Node v6.5\n(decoding and encoding a sample of 439 vector tiles, 22.6 MB total):\n\n- **pbf** decode: 387ms, or 57 MB/s\n- **pbf** encode: 396ms, or 56 MB/s\n- **protocol-buffers** decode: 837ms, or 26 MB/s\n- **protocol-buffers** encode: 4197ms, or 5 MB/s\n- **JSON.parse**: 1540ms, or 125 MB/s (parsing an equivalent 77.5 MB JSON file)\n- **JSON.stringify**: 607ms, or 49 MB/s\n\n## Examples\n\n#### Using Compiled Code\n\nInstall `pbf` and compile a JavaScript module from a `.proto` file:\n\n```bash\n$ npm install -g pbf\n$ pbf example.proto \u003e example.js\n```\n\nThen read and write objects using the module like this:\n\n```js\nimport Pbf from 'pbf';\nimport {readExample, writeExample} from './example.js';\n\n// read\nvar obj = readExample(new Pbf(buffer));\n\n// write\nconst pbf = new Pbf();\nwriteExample(obj, pbf);\nconst buffer = pbf.finish();\n```\n\nAlternatively, you can compile a protobuf schema file directly in the code:\n\n```js\nimport {compile} from 'pbf/compile';\nimport schema from 'protocol-buffers-schema';\n\nconst proto = schema.parse(fs.readFileSync('example.proto'));\nconst {readExample, writeExample} = compile(proto);\n```\n\n#### Custom Reading\n\n```js\nvar data = new Pbf(buffer).readFields(readData, {});\n\nfunction readData(tag, data, pbf) {\n    if (tag === 1) data.name = pbf.readString();\n    else if (tag === 2) data.version = pbf.readVarint();\n    else if (tag === 3) data.layer = pbf.readMessage(readLayer, {});\n}\nfunction readLayer(tag, layer, pbf) {\n    if (tag === 1) layer.name = pbf.readString();\n    else if (tag === 3) layer.size = pbf.readVarint();\n}\n```\n\n#### Custom Writing\n\n```js\nvar pbf = new Pbf();\nwriteData(data, pbf);\nvar buffer = pbf.finish();\n\nfunction writeData(data, pbf) {\n    pbf.writeStringField(1, data.name);\n    pbf.writeVarintField(2, data.version);\n    pbf.writeMessage(3, writeLayer, data.layer);\n}\nfunction writeLayer(layer, pbf) {\n    pbf.writeStringField(1, layer.name);\n    pbf.writeVarintField(2, layer.size);\n}\n```\n\n## Install\n\nInstall using NPM with `npm install pbf`, then import as a module:\n\n```js\nimport Pbf from 'pbf';\n```\n\nOr use as a module directly in the browser with [jsDelivr](https://www.jsdelivr.com/esm):\n\n```html\n\u003cscript type=\"module\"\u003e\n    import Pbf from 'https://cdn.jsdelivr.net/npm/pbf/+esm';\n\u003c/script\u003e\n```\n\nAlternatively, there's a browser bundle with a `Pbf` global variable:\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/pbf\"\u003e\u003c/script\u003e\n```\n\n## API\n\nCreate a `Pbf` object, optionally given a `Buffer` or `Uint8Array` as input data:\n\n```js\n// parse a pbf file from disk in Node\nconst pbf = new Pbf(fs.readFileSync('data.pbf'));\n\n// parse a pbf file in a browser after an ajax request with responseType=\"arraybuffer\"\nconst pbf = new Pbf(new Uint8Array(xhr.response));\n```\n\n`Pbf` object properties:\n\n```js\npbf.length; // length of the underlying buffer\npbf.pos; // current offset for reading or writing\n```\n\n#### Reading\n\nRead a sequence of fields:\n\n```js\npbf.readFields((tag) =\u003e {\n    if (tag === 1) pbf.readVarint();\n    else if (tag === 2) pbf.readString();\n    else ...\n});\n```\n\nIt optionally accepts an object that will be passed to the reading function for easier construction of decoded data,\nand also passes the `Pbf` object as a third argument:\n\n```js\nconst result = pbf.readFields(readField, {})\n\nfunction readField(tag, result, pbf) {\n    if (tag === 1) result.id = pbf.readVarint();\n}\n```\n\nTo read an embedded message, use `pbf.readMessage(fn[, obj])` (in the same way as `read`).\n\nRead values:\n\n```js\nconst value = pbf.readVarint();\nconst str = pbf.readString();\nconst numbers = pbf.readPackedVarint();\n```\n\nFor lazy or partial decoding, simply save the position instead of reading a value,\nthen later set it back to the saved value and read:\n\n```js\nconst fooPos = -1;\npbf.readFields((tag) =\u003e {\n    if (tag === 1) fooPos = pbf.pos;\n});\n...\npbf.pos = fooPos;\npbf.readMessage(readFoo);\n```\n\nScalar reading methods:\n\n* `readVarint(isSigned)` (pass `true` if you expect negative varints)\n* `readSVarint()`\n* `readFixed32()`\n* `readFixed64()`\n* `readSFixed32()`\n* `readSFixed64()`\n* `readBoolean()`\n* `readFloat()`\n* `readDouble()`\n* `readString()`\n* `readBytes()`\n* `skip(value)`\n\nPacked reading methods:\n\n* `readPackedVarint(arr, isSigned)` (appends read items to `arr`)\n* `readPackedSVarint(arr)`\n* `readPackedFixed32(arr)`\n* `readPackedFixed64(arr)`\n* `readPackedSFixed32(arr)`\n* `readPackedSFixed64(arr)`\n* `readPackedBoolean(arr)`\n* `readPackedFloat(arr)`\n* `readPackedDouble(arr)`\n\n#### Writing\n\nWrite values:\n\n```js\npbf.writeVarint(123);\npbf.writeString(\"Hello world\");\n```\n\nWrite an embedded message:\n\n```js\npbf.writeMessage(1, writeObj, obj);\n\nfunction writeObj(obj, pbf) {\n    pbf.writeStringField(obj.name);\n    pbf.writeVarintField(obj.version);\n}\n```\n\nField writing methods:\n\n* `writeVarintField(tag, val)`\n* `writeSVarintField(tag, val)`\n* `writeFixed32Field(tag, val)`\n* `writeFixed64Field(tag, val)`\n* `writeSFixed32Field(tag, val)`\n* `writeSFixed64Field(tag, val)`\n* `writeBooleanField(tag, val)`\n* `writeFloatField(tag, val)`\n* `writeDoubleField(tag, val)`\n* `writeStringField(tag, val)`\n* `writeBytesField(tag, buffer)`\n\nPacked field writing methods:\n\n* `writePackedVarint(tag, val)`\n* `writePackedSVarint(tag, val)`\n* `writePackedSFixed32(tag, val)`\n* `writePackedSFixed64(tag, val)`\n* `writePackedBoolean(tag, val)`\n* `writePackedFloat(tag, val)`\n* `writePackedDouble(tag, val)`\n\nScalar writing methods:\n\n* `writeVarint(val)`\n* `writeSVarint(val)`\n* `writeSFixed32(val)`\n* `writeSFixed64(val)`\n* `writeBoolean(val)`\n* `writeFloat(val)`\n* `writeDouble(val)`\n* `writeString(val)`\n* `writeBytes(buffer)`\n\nMessage writing methods:\n\n* `writeMessage(tag, fn[, obj])`\n* `writeRawMessage(fn[, obj])`\n\nMisc methods:\n\n* `realloc(minBytes)` - pad the underlying buffer size to accommodate the given number of bytes;\n   note that the size increases exponentially, so it won't necessarily equal the size of data written\n* `finish()` - make the current buffer ready for reading and return the data as a buffer slice\n\nFor an example of a real-world usage of the library, see [vector-tile-js](https://github.com/mapbox/vector-tile-js).\n\n\n## Proto Schema to JavaScript\n\nIf installed globally, `pbf` provides a binary that compiles `proto` files into JavaScript modules. Usage:\n\n```bash\n$ pbf \u003cproto_path\u003e [--no-write] [--no-read] [--legacy]\n```\n\nThe `--no-write` and `--no-read` switches remove corresponding code in the output.\nThe `--legacy` switch makes it generate a CommonJS module instead of ESM.\n\n`Pbf` will generate `read\u003cIdentifier\u003e` and `write\u003cIdentifier\u003e` functions for every message in the schema. For nested messages, their names will be concatenated — e.g. `Message` inside `Test` will produce `readTestMessage` and `writeTestMessage` functions.\n\n\n* `read(pbf)` - decodes an object from the given `Pbf` instance.\n* `write(obj, pbf)` - encodes an object into the given `Pbf` instance (usually empty).\n\nThe resulting code is clean and simple, so it's meant to be customized.\n","funding_links":[],"categories":["JavaScript","library"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmapbox%2Fpbf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmapbox%2Fpbf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmapbox%2Fpbf/lists"}