borc
A fast, synchronous CBOR encoder and decoder for JavaScript, built around an asm.js parser.
Repository Health
Technical Analysis
borc encodes and decodes data in the Concise Binary Object Representation (CBOR, RFC 7049), a compact binary alternative to JSON. It is a fork of node-cbor that strips out streaming and async processing in favor of a minimal synchronous API, trading flexibility for raw decode speed via a hand-written asm.js parser.
The library supports the common JavaScript value set out of the box — booleans, numbers (including -0, NaN, and infinities), strings, arrays, Sets, objects, Maps, Buffers, Dates, RegExps, URLs, and arbitrary-precision numbers via bignumber.js — plus CBOR’s semantic tag mechanism for extending both encoding and decoding with custom types. It also ships a small CLI (cbor2json, json2cbor, cbor2diag, cbor2comment) for converting between CBOR and JSON/diagnostic notation from the command line.
What You Get
- Synchronous
encode/decode/decodeFirst/decodeAllfunctions with no streams or callbacks to manage - An asm.js-optimized decoder for fast parsing of binary CBOR payloads in both Node.js and browsers
- Built-in support for Buffers, Dates, RegExps, URLs, Maps, Sets, and arbitrary-precision numbers via bignumber.js
- A custom-tag system for both encoding (
encodeCBOR) and decoding (opts.tags) application-specific types - A
leveldb-compatible encoding object for direct use as a LevelDB/LevelUp value encoding - Command-line tools (cbor2json, json2cbor, cbor2diag, cbor2comment) for CBOR/JSON/diagnostic conversion outside of code
Common Use Cases
- Compact wire format for IoT/CoAP protocols - services exchanging small binary payloads over constrained networks use borc to encode/decode CBOR instead of verbose JSON
- IPFS/libp2p style binary object storage - projects storing structured objects as compact binary blobs (its README credits IPFS/Protocol Labs usage) rely on borc for synchronous serialization
- High-throughput binary parsing - services that need to decode many CBOR messages per second reach for borc’s asm.js parser over async-first alternatives
- LevelDB/LevelUp value encoding - applications storing CBOR-encoded values in a LevelDB-backed store plug in borc’s
leveldbexport directly as a custom encoding - CLI conversion between CBOR and JSON - developers debugging binary payloads pipe files through the bundled cbor2json/json2cbor/cbor2diag scripts
Under The Hood
Architecture
borc is organized as a small set of single-purpose modules re-exported from src/index.js: encoder.js implements an Encoder class that walks JavaScript values and writes CBOR bytes (with a pluggable semanticTypes table for custom classes like URL and Bignumber), decoder.js implements a Decoder class that wraps a hand-written asm.js state machine (decoder.asm.js) driven over a shared ArrayBuffer heap, and simple.js/tagged.js model CBOR’s simple-value and tagged-value wrapper types. constants.js centralizes the CBOR major-type and additional-info bit layout used by both encoder and decoder, keeping the wire-format knowledge in one place. The design deliberately drops the streaming/async layers present in its parent project (node-cbor) in favor of synchronous calls, so the core abstraction to reason about is the asm.js parser callback table — if that contract changes, both decoder.js and decoder.asm.js must move together.
Tech Stack
The library is plain JavaScript (CommonJS) with a handful of small runtime dependencies: bignumber.js for arbitrary-precision numbers, buffer and readable-stream for cross-platform Buffer/stream shims, ieee754 for float encoding, iso-url for a consistent URL implementation across Node and browsers, commander for the bundled CLI scripts, and json-text-sequence for the diagnostic tooling. Build, lint, test, docs, and release tasks all delegate to Protocol Labs’ aegir toolchain, which runs the same test suite against both Node and browser/webworker targets; CI (Travis) exercises Linux/macOS/Windows on Node and Chrome/Firefox.
Code Quality
Tests are split across two runners bridged by aegir: .spec.js files use a Mocha-style describe/it API with aegir’s bundled chai assertions, while a couple of .ava.js files use the ava runner directly. Coverage spans encoder/decoder round-tripping, official CBOR test vectors from the cbor/test-vectors project, diagnostic-notation output, and fuzz-style input via the garbage package. Error handling in the decoder is explicit (invalid input throws rather than failing silently). Linting is enforced through aegir lint, and CI runs on every push, though the project has had no commits since 2021 and open issues have accumulated unaddressed.
API Design
The public surface mirrors Node’s built-in JSON.parse/JSON.stringify shape (cbor.encode, cbor.decode, cbor.decodeFirst, cbor.decodeAll), which keeps the learning curve low for anyone coming from JSON handling. Extending the format for custom classes is a single method (encodeCBOR on the class, or a tags map passed to the Decoder constructor), and the leveldb export packages the codec into the shape LevelUp expects with zero extra glue code. The tradeoff is that documentation lives mostly in the README and hosted API docs rather than inline guides, and the asm.js decoding path is effectively a black box unless a consumer reads decoder.asm.js directly.