A low-level, lightweight protocol buffers implementation in JavaScript.
Installations
npm install pbf
Score
98.5
Supply Chain
100
Quality
85.5
Maintenance
100
Vulnerability
100
License
Developer
mapbox
Developer Guide
Module System
ESM
Min. Node Version
Typescript Support
Yes
Node Version
20.12.1
NPM Version
10.5.1
Statistics
799 Stars
272 Commits
107 Forks
138 Watching
7 Branches
550 Contributors
Updated on 28 Nov 2024
Bundle Size
8.94 kB
Minified
2.39 kB
Minified + Gzipped
Languages
JavaScript (98.16%)
HTML (1.84%)
Total Downloads
Cumulative downloads
Total Downloads
244,050,211
Last day
-11.5%
291,430
Compared to previous day
Last week
-0.8%
1,651,133
Compared to previous week
Last month
7.2%
7,037,430
Compared to previous month
Last year
20.5%
72,189,363
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
pbf
A low-level, fast, ultra-lightweight (3KB gzipped) JavaScript library for decoding and encoding 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.
Performance
This library is extremely fast — much faster than native JSON.parse
/JSON.stringify
and the protocol-buffers module.
Here's a result from running a real-world benchmark on Node v6.5
(decoding and encoding a sample of 439 vector tiles, 22.6 MB total):
- pbf decode: 387ms, or 57 MB/s
- pbf encode: 396ms, or 56 MB/s
- protocol-buffers decode: 837ms, or 26 MB/s
- protocol-buffers encode: 4197ms, or 5 MB/s
- JSON.parse: 1540ms, or 125 MB/s (parsing an equivalent 77.5 MB JSON file)
- JSON.stringify: 607ms, or 49 MB/s
Examples
Using Compiled Code
Install pbf
and compile a JavaScript module from a .proto
file:
1$ npm install -g pbf 2$ pbf example.proto > example.js
Then read and write objects using the module like this:
1import Pbf from 'pbf'; 2import {readExample, writeExample} from './example.js'; 3 4// read 5var obj = readExample(new Pbf(buffer)); 6 7// write 8const pbf = new Pbf(); 9writeExample(obj, pbf); 10const buffer = pbf.finish();
Alternatively, you can compile a protobuf schema file directly in the code:
1import {compile} from 'pbf/compile'; 2import schema from 'protocol-buffers-schema'; 3 4const proto = schema.parse(fs.readFileSync('example.proto')); 5const {readExample, writeExample} = compile(proto);
Custom Reading
1var data = new Pbf(buffer).readFields(readData, {});
2
3function readData(tag, data, pbf) {
4 if (tag === 1) data.name = pbf.readString();
5 else if (tag === 2) data.version = pbf.readVarint();
6 else if (tag === 3) data.layer = pbf.readMessage(readLayer, {});
7}
8function readLayer(tag, layer, pbf) {
9 if (tag === 1) layer.name = pbf.readString();
10 else if (tag === 3) layer.size = pbf.readVarint();
11}
Custom Writing
1var pbf = new Pbf();
2writeData(data, pbf);
3var buffer = pbf.finish();
4
5function writeData(data, pbf) {
6 pbf.writeStringField(1, data.name);
7 pbf.writeVarintField(2, data.version);
8 pbf.writeMessage(3, writeLayer, data.layer);
9}
10function writeLayer(layer, pbf) {
11 pbf.writeStringField(1, layer.name);
12 pbf.writeVarintField(2, layer.size);
13}
Install
Install using NPM with npm install pbf
, then import as a module:
1import Pbf from 'pbf';
Or use as a module directly in the browser with jsDelivr:
1<script type="module"> 2 import Pbf from 'https://cdn.jsdelivr.net/npm/pbf/+esm'; 3</script>
Alternatively, there's a browser bundle with a Pbf
global variable:
1<script src="https://cdn.jsdelivr.net/npm/pbf"></script>
API
Create a Pbf
object, optionally given a Buffer
or Uint8Array
as input data:
1// parse a pbf file from disk in Node
2const pbf = new Pbf(fs.readFileSync('data.pbf'));
3
4// parse a pbf file in a browser after an ajax request with responseType="arraybuffer"
5const pbf = new Pbf(new Uint8Array(xhr.response));
Pbf
object properties:
1pbf.length; // length of the underlying buffer 2pbf.pos; // current offset for reading or writing
Reading
Read a sequence of fields:
1pbf.readFields((tag) => { 2 if (tag === 1) pbf.readVarint(); 3 else if (tag === 2) pbf.readString(); 4 else ... 5});
It optionally accepts an object that will be passed to the reading function for easier construction of decoded data,
and also passes the Pbf
object as a third argument:
1const result = pbf.readFields(readField, {})
2
3function readField(tag, result, pbf) {
4 if (tag === 1) result.id = pbf.readVarint();
5}
To read an embedded message, use pbf.readMessage(fn[, obj])
(in the same way as read
).
Read values:
1const value = pbf.readVarint(); 2const str = pbf.readString(); 3const numbers = pbf.readPackedVarint();
For lazy or partial decoding, simply save the position instead of reading a value, then later set it back to the saved value and read:
1const fooPos = -1; 2pbf.readFields((tag) => { 3 if (tag === 1) fooPos = pbf.pos; 4}); 5... 6pbf.pos = fooPos; 7pbf.readMessage(readFoo);
Scalar reading methods:
readVarint(isSigned)
(passtrue
if you expect negative varints)readSVarint()
readFixed32()
readFixed64()
readSFixed32()
readSFixed64()
readBoolean()
readFloat()
readDouble()
readString()
readBytes()
skip(value)
Packed reading methods:
readPackedVarint(arr, isSigned)
(appends read items toarr
)readPackedSVarint(arr)
readPackedFixed32(arr)
readPackedFixed64(arr)
readPackedSFixed32(arr)
readPackedSFixed64(arr)
readPackedBoolean(arr)
readPackedFloat(arr)
readPackedDouble(arr)
Writing
Write values:
1pbf.writeVarint(123); 2pbf.writeString("Hello world");
Write an embedded message:
1pbf.writeMessage(1, writeObj, obj);
2
3function writeObj(obj, pbf) {
4 pbf.writeStringField(obj.name);
5 pbf.writeVarintField(obj.version);
6}
Field writing methods:
writeVarintField(tag, val)
writeSVarintField(tag, val)
writeFixed32Field(tag, val)
writeFixed64Field(tag, val)
writeSFixed32Field(tag, val)
writeSFixed64Field(tag, val)
writeBooleanField(tag, val)
writeFloatField(tag, val)
writeDoubleField(tag, val)
writeStringField(tag, val)
writeBytesField(tag, buffer)
Packed field writing methods:
writePackedVarint(tag, val)
writePackedSVarint(tag, val)
writePackedSFixed32(tag, val)
writePackedSFixed64(tag, val)
writePackedBoolean(tag, val)
writePackedFloat(tag, val)
writePackedDouble(tag, val)
Scalar writing methods:
writeVarint(val)
writeSVarint(val)
writeSFixed32(val)
writeSFixed64(val)
writeBoolean(val)
writeFloat(val)
writeDouble(val)
writeString(val)
writeBytes(buffer)
Message writing methods:
writeMessage(tag, fn[, obj])
writeRawMessage(fn[, obj])
Misc methods:
realloc(minBytes)
- pad the underlying buffer size to accommodate the given number of bytes; note that the size increases exponentially, so it won't necessarily equal the size of data writtenfinish()
- make the current buffer ready for reading and return the data as a buffer slice
For an example of a real-world usage of the library, see vector-tile-js.
Proto Schema to JavaScript
If installed globally, pbf
provides a binary that compiles proto
files into JavaScript modules. Usage:
1$ pbf <proto_path> [--no-write] [--no-read] [--legacy]
The --no-write
and --no-read
switches remove corresponding code in the output.
The --legacy
switch makes it generate a CommonJS module instead of ESM.
Pbf
will generate read<Identifier>
and write<Identifier>
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.
read(pbf)
- decodes an object from the givenPbf
instance.write(obj, pbf)
- encodes an object into the givenPbf
instance (usually empty).
The resulting code is clean and simple, so it's meant to be customized.
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: BSD 3-Clause "New" or "Revised" License: LICENSE:0
Reason
security policy file detected
Details
- Info: security policy file detected: github.com/mapbox/.github/SECURITY.md:1
- Info: Found linked content: github.com/mapbox/.github/SECURITY.md:1
- Info: Found disclosure, vulnerability, and/or timelines in security policy: github.com/mapbox/.github/SECURITY.md:1
- Info: Found text in security policy: github.com/mapbox/.github/SECURITY.md:1
Reason
4 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6
- Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
Reason
SAST tool is not run on all commits -- score normalized to 6
Details
- Warn: 10 commits out of 16 are checked with a SAST tool
Reason
branch protection is not maximal on development and all release branches
Details
- Info: 'allow deletion' disabled on branch 'main'
- Info: 'force pushes' disabled on branch 'main'
- Warn: 'branch protection settings apply to administrators' is disabled on branch 'main'
- Warn: 'stale review dismissal' is disabled on branch 'main'
- Warn: required approving review count is 1 on branch 'main'
- Warn: codeowners review is not required on branch 'main'
- Warn: 'last push approval' is disabled on branch 'main'
- Warn: no status checks found to merge onto branch 'main'
- Info: PRs are required in order to make changes on branch 'main'
Reason
dependency not pinned by hash detected -- score normalized to 3
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node.yml:8: update your workflow using https://app.stepsecurity.io/secureworkflow/mapbox/pbf/node.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/mapbox/pbf/node.yml/main?enable=pin
- Info: 0 out of 2 GitHub-owned GitHubAction dependencies pinned
- Info: 1 out of 1 npmCommand dependencies pinned
Reason
Found 5/21 approved changesets -- score normalized to 2
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/node.yml:1
- Info: no jobLevel write permissions found
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Score
4.9
/10
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More