User Rating 0.0
Total Usage 0 times
Cap'n Proto Text
JSON Output
JSON will appear here…
Is this tool helpful?

Your feedback helps us improve.

About

Cap'n Proto text encoding is a human-readable serialization format used for debugging, configuration, and data interchange within the Cap'n Proto ecosystem. Converting it to JSON is not trivial. The format uses parenthesized struct notation (field = value), supports nested structures, typed lists with bracket syntax, and integer values that can exceed JavaScript's Number.MAX_SAFE_INTEGER (253 − 1). A naive parser that casts integers to Number will silently corrupt large identifiers and timestamps. This tool implements a recursive descent parser that emits integers as strings, preserving bit-exact fidelity. It handles escape sequences in string literals, boolean and void types, hexadecimal notation, and arbitrarily deep nesting.

Incorrect conversion can propagate corrupted IDs into downstream systems, break schema-aware tooling, or silently truncate 64-bit node identifiers. The parser reports errors with position information so malformed input is caught immediately rather than producing subtly wrong output. Note: this tool approximates the text encoding grammar as documented in the Cap'n Proto specification. Edge cases involving inline union syntax or raw data fields may require manual review.

capnproto text to json capnp converter serialization data converter capn proto parser

Formulas

The converter implements a recursive descent parser. The grammar can be expressed informally as:

Value Struct | List | String | Number | Bool | void | Ident
Struct ( Field (, Field)* )
Field Ident = Value
List [ Value (, Value)* ]
Number [] ( 0xHexDigits | Digits [.Digits] [eExp] )

Where Ident is any alphabetic identifier. Integers (no decimal point, no exponent) are emitted as JSON strings to prevent precision loss beyond Number.MAX_SAFE_INTEGER = 253 1 = 9007199254740991. Floating-point values (containing . or e) are parsed as native parseFloat since IEEE 754 double precision is the expected representation. The keyword void maps to JSON null. Boolean literals TRUE and FALSE map to native JSON booleans. Bare identifiers (enum values) are emitted as JSON strings.

Reference Data

Cap'n Proto Text ConstructSyntax ExampleJSON OutputNotes
Simple field(name = "Alice"){"name": "Alice"}String values preserve escapes
Integer field(id = 12345678901234567890){"id": "12345678901234567890"}Emitted as string to prevent overflow
Hex integer(flags = 0xff00){"flags": "0xff00"}Preserved as hex string
Negative integer(offset = -42){"offset": "-42"}Sign preserved in string
Float field(ratio = 3.14){"ratio": 3.14}Parsed as JS number (no overflow risk for typical floats)
Boolean field(active = true){"active": true}Native JSON boolean
Void field(nothing = void){"nothing": null}Void maps to null
Text list(tags = ["a", "b"]){"tags": ["a", "b"]}Standard JSON array
Integer list(ids = [1, 2, 3]){"ids": ["1", "2", "3"]}Each integer is a string
Nested struct(person = (name = "Bob", age = 30)){"person": {"name": "Bob", "age": "30"}}Recursive parsing
List of structs(items = [(id = 1), (id = 2)]){"items": [{"id": "1"}, {"id": "2"}]}Mixed nesting supported
Empty struct(){}Valid empty object
Empty list(data = []){"data": []}Valid empty array
Escape sequences(msg = "line1\nline2"){"msg": "line1\nline2"}Standard C-style escapes
Multiple fields(a = 1, b = 2, c = 3){"a": "1", "b": "2", "c": "3"}Comma-separated
Enum-like identifier(status = active){"status": "active"}Bare identifiers become strings (except true/false/void)
Data literal(raw = 0x"48656c6c6f"){"raw": "48656c6c6f"}Hex data as string
Top-level list value["x", "y", "z"]["x", "y", "z"]No wrapping struct needed
Whitespace tolerance( a = 1 ){"a": "1"}Whitespace is insignificant
Unicode strings(label = "日本語"){"label": "日本語"}UTF-8 passthrough

Frequently Asked Questions

Cap'n Proto schemas frequently use 64-bit unsigned integers for node IDs, timestamps, and unique identifiers. JavaScript's Number type uses IEEE 754 double-precision, which only guarantees exact integer representation up to 2^53 − 1 (9007199254740991). Any integer beyond this threshold would be silently rounded, corrupting IDs. Emitting all integers as strings preserves bit-exact values. Downstream consumers can parse them with BigInt or language-appropriate arbitrary-precision types.
The parser explicitly checks for the keywords "true", "false", and "void" (case-sensitive) before falling back to treating a bare identifier as an enum string value. In Cap'n Proto text encoding, booleans are lowercase. If your schema uses an enum variant named "true", it would conflict - this matches the behavior of the canonical capnp tool, which reserves these keywords.
No. This tool parses only the human-readable text encoding format, which is what "capnp decode" and "capnp eval" produce. Binary-encoded messages require schema-aware deserialization with proper segment table parsing, pointer traversal, and type-specific decoding. Use the capnp command-line tool to convert binary to text first, then paste the text output here.
Cap'n Proto text encoding represents union variants as regular named fields within the struct parentheses. The parser treats them identically to any other field assignment. Group fields appear as nested struct values. The output JSON will contain the union discriminant field name as a key with its value. However, unnamed unions using ":" syntax in some older text dumps may require manual adjustment before parsing.
Yes. The parser processes fields sequentially and builds the JavaScript object in insertion order. JSON.stringify preserves insertion order for string keys per the ECMAScript specification. The output JSON fields will appear in the same order as the input Cap'n Proto text fields.
Cap'n Proto text encoding represents Data fields as hex strings with the syntax 0x"48656c6c6f". The parser recognizes this pattern and emits the hex content as a plain JSON string (e.g., "48656c6c6f"). No binary decoding is performed since JSON has no native binary type. You can decode the hex string in your application layer.