Cap'n Proto Text to JSON Converter
Convert Cap'n Proto text-encoded data to JSON online. Parses structs, lists, nested fields, and integers as strings to prevent overflow.
JSON will appear here…
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.
Formulas
The converter implements a recursive descent parser. The grammar can be expressed informally as:
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 Construct | Syntax Example | JSON Output | Notes |
|---|---|---|---|
| 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 |