BinSchema Type Reference

BinSchema Type System

Overview

Complete reference for all built-in types supported by BinSchema, including wire format specifications and code generation mappings.

This reference documents the overall JSON structure used by BinSchema, the optional protocol metadata layer, and the built-in field types you can use when defining schemas.

Schema Structure

BinSchema documents are JSON (or JSON5) files with three top-level sections. Only types is required; the other sections layer additional context or reusable defaults.

You can use JSON5 authoring conveniences—comments, trailing commas, and hex literals are accepted when loading schemas.

Top-Level Properties
Property Type Required Description
config object optional Optional global defaults for endianness and bit ordering. Individual fields can override these settings.
types record<string, TypeDef> required Map of type names to type definitions. Keys must start with an uppercase letter so they never collide with built-in primitives.
protocol ProtocolDefinition optional Optional protocol metadata for documenting message-oriented systems. When present, describes headers, message codes, and grouping.

Config Object

The optional config object defines defaults for every field in the schema. Values can be overridden by individual field definitions.

Config Properties
Property Type Required Description
endianness enum ("big_endian" | "little_endian") optional Default byte order for multi-byte numeric values. Use field-level endianness to override.
bit_order enum ("msb_first" | "lsb_first") optional Default bit ordering for bitfields. Most-significant-bit first (msb_first) or least-significant-bit first (lsb_first).

Type Definitions

Each entry in the types map defines a reusable structure or alias:

Minimal Types-Only Schema
{
  "config": {
    "endianness": "big_endian"
  },
  "types": {
    "FrameHeader": {
      "sequence": [
        {
          "name": "length",
          "type": "uint16"
        },
        {
          "name": "type",
          "type": "uint8"
        }
      ]
    },
    "Ping": {
      "sequence": [
        {
          "name": "timestamp",
          "type": "uint64"
        }
      ]
    }
  }
}

Protocol Definition

The optional protocol block documents message-oriented protocols built on top of the binary types. It links a frame header to payload types and captures metadata for documentation.

Protocol Properties
Property Type Required Description
name string required Human-readable protocol name. Appears in generated documentation.
version string required Protocol version string (for example, "1.0").
types_schema string required Path to the BinarySchema JSON file that defines the types section. Resolved relative to the protocol JSON file.
description string optional Optional overview paragraph shown at the top of generated docs.
header_format string optional Name of the type in types that describes the frame header. Required for frame diagrams and header validation.
header_size_field string optional Name of the header field that stores payload size. Used to auto-fill frame examples.
discriminator_field string optional Header field (supports dot notation for bitfields) that selects which message payload is on the wire. Required when documenting multiple message codes.
header_example { decoded: any } optional Sample decoded header values shown in generated diagrams. BinSchema fills in missing size fields when possible.
field_descriptions record<string, string> optional Map of Type.field → human-readable description. Applied across headers and payload types.
messages ProtocolMessage[] required List of documented message codes and payload types. Used to drive tables and payload renderings.
message_groups MessageGroup[] optional Optional organization layer that groups message codes into categories.
constants record<string, ProtocolConstant> optional Named numeric/string constants referenced by the protocol.
notes string[] optional Protocol-wide notes rendered as bullet points.
ProtocolMessage Properties
Property Type Required Description
code string | number required Unique message identifier expressed as hex (for example, "0x8A"). Numeric values are converted to uppercase hex on load.
name string required Message constant name such as "AUTH_REQUEST".
direction enum ("client_to_server" | "server_to_client" | "bidirectional") required Traffic direction hint for documentation tables.
payload_type string required Type name from the BinarySchema types map that encodes the payload.
description string optional Short summary of what the message conveys.
notes string | string[] optional Extended guidance on when or how to use the message. Supports Markdown-style bold and italic.
example { description: string; bytes: number[]; decoded?: any } optional Example payload illustrating bytes on the wire. Combined with header_example to build frame diagrams.
since string optional Protocol version where the message was introduced.
deprecated string optional Marks the version where the message was deprecated.
MessageGroup Properties
Property Type Required Description
name string required Display name for the group (for example, "Authentication").
messages Array<string | number> required List of message codes included in the group.
description string optional Optional description shown beneath the group heading.
ProtocolConstant Properties
Property Type Required Description
value number | string required Literal constant value.
description string required Explanation of how the constant is used.
type string optional Optional type reference that clarifies the constant's units or bit width.
Usage Notes
  • discriminator_field becomes mandatory when more than one message code is listed. BinSchema validates the field exists in the header type.
  • Message codes provided as integers are automatically converted to uppercase hex strings (for example, 0x01).
  • field_descriptions entries can target either header fields (for example, FrameHeader.length) or payload fields (for example, AuthRequest.nickname).
  • When a message provides an example, the generator combines it with header_example to render fully annotated frame diagrams.
Schema with Protocol Metadata (excerpt)
{
  "types": {
    "FrameHeader": {
      "sequence": [
        {
          "name": "length",
          "type": "uint32"
        },
        {
          "name": "version",
          "type": "uint8"
        },
        {
          "name": "type",
          "type": "uint8"
        }
      ]
    },
    "Ping": {
      "sequence": [
        {
          "name": "timestamp",
          "type": "uint64"
        }
      ]
    }
  },
  "protocol": {
    "name": "Example Protocol",
    "version": "1.0",
    "types_schema": "./example-types.json",
    "header_format": "FrameHeader",
    "discriminator_field": "type",
    "messages": [
      {
        "code": 0x10,
        "name": "PING",
        "direction": "client_to_server",
        "payload_type": "Ping"
      },
      {
        "code": 0x90,
        "name": "PONG",
        "direction": "server_to_client",
        "payload_type": "Ping"
      }
    ]
  }
}

Primitive Types

Unsigned Integers

uint8

8-bit Unsigned Integer

Fixed-width 8-bit unsigned integer (0-255). Single byte, no endianness concerns.

Use for: Message type codes, flags, single-byte counters, status codes
Wire format: 1 byte (0x00-0xFF)
Properties
Property Type Required Description
name string required Field name
type literal "uint8" required Field type (always 'uint8')
const number (min: 0, max: 255) optional Constant value for this field (used as discriminator in choice types). Mutually exclusive with 'computed'.
computed object optional Marks this field as automatically computed (e.g., length_of, crc32_of). Mutually exclusive with 'const'.
description string optional Human-readable description of this field
Generated Code
Type: number
  • JavaScript Number type
  • Safe for all uint8 values
Type: uint8
  • Native Go uint8 type
  • Also known as byte
Type: u8
  • Native Rust u8 type
Examples
Schema Definition Example Values
[
  {
    "name": "version",
    "type": "uint8"
  },
  {
    "name": "flags",
    "type": "uint8",
    "description": "Feature flags"
  },
  {
    "name": "message_type",
    "type": "uint8"
  }
]
{
  version: 1,
  flags: 0x01,
  message_type: 0x20
}
Schema Definition Example Values
[
  {
    "name": "version",
    "type": "uint8"
  },
  {
    "name": "flags",
    "type": "uint8",
    "description": "Feature flags"
  },
  {
    "name": "message_type",
    "type": "uint8"
  }
]
Message{
  Version:     1,
  Flags:       0x01,
  MessageType: 0x20,
}
Schema Definition Example Values
[
  {
    "name": "version",
    "type": "uint8"
  },
  {
    "name": "flags",
    "type": "uint8",
    "description": "Feature flags"
  },
  {
    "name": "message_type",
    "type": "uint8"
  }
]
Message {
  version: 1,
  flags: 0x01,
  message_type: 0x20,
}

uint16

16-bit Unsigned Integer

Fixed-width 16-bit unsigned integer (0-65535). Respects endianness configuration (big-endian or little-endian).

Use for: Port numbers, message lengths, medium-range counters, message IDs
Wire format: 2 bytes, byte order depends on endianness setting
Properties
Property Type Required Description
name string required Field name
type literal "uint16" required Field type (always 'uint16')
const number (min: 0, max: 65535) optional Constant value for this field (used as discriminator in choice types). Mutually exclusive with 'computed'.
computed object optional Marks this field as automatically computed (e.g., length_of, crc32_of). Mutually exclusive with 'const'.
endianness enum ("big_endian" | "little_endian") optional Byte order for multi-byte values (big_endian or little_endian). Overrides global config if specified.
description string optional Human-readable description of this field
Generated Code
Type: number
  • JavaScript Number type
  • Safe for all uint16 values
Type: uint16
  • Native Go uint16 type
Type: u16
  • Native Rust u16 type
Notes
  • Default endianness is inherited from global config
  • Can override with field-level `endianness` property
  • Network protocols typically use big-endian
Examples
[
  {
    "name": "port",
    "type": "uint16",
    "endianness": "big_endian"
  },
  {
    "name": "content_length",
    "type": "uint16"
  },
  {
    "name": "message_id",
    "type": "uint16",
    "endianness": "little_endian"
  }
]

uint32

32-bit Unsigned Integer

Fixed-width 32-bit unsigned integer (0-4294967295). Respects endianness configuration.

Use for: Timestamps, large counters, IP addresses, file sizes, CRCs
Wire format: 4 bytes, byte order depends on endianness setting
Properties
Property Type Required Description
name string required Field name
type literal "uint32" required Field type (always 'uint32')
const number (min: 0, max: 4294967295) optional Constant value for this field (used as discriminator in choice types). Mutually exclusive with 'computed'.
computed object optional Marks this field as automatically computed (e.g., length_of, crc32_of). Mutually exclusive with 'const'.
endianness enum ("big_endian" | "little_endian") optional Byte order for multi-byte values (big_endian or little_endian). Overrides global config if specified.
description string optional Human-readable description of this field
Generated Code
Type: number
  • JavaScript Number type
  • Safe for all uint32 values
Type: uint32
  • Native Go uint32 type
Type: u32
  • Native Rust u32 type
Notes
  • Common choice for Unix timestamps (seconds since epoch)
  • IPv4 addresses are typically stored as uint32
Examples
Schema Definition Example Values
[
  {
    "name": "timestamp",
    "type": "uint32",
    "endianness": "big_endian"
  },
  {
    "name": "file_size",
    "type": "uint32"
  },
  {
    "name": "crc32",
    "type": "uint32",
    "endianness": "little_endian"
  }
]
{
  timestamp: 1704067200,
  file_size: 1048576,
  crc32: 0xDEADBEEF
}
Schema Definition Example Values
[
  {
    "name": "timestamp",
    "type": "uint32",
    "endianness": "big_endian"
  },
  {
    "name": "file_size",
    "type": "uint32"
  },
  {
    "name": "crc32",
    "type": "uint32",
    "endianness": "little_endian"
  }
]
Message{
  Timestamp: 1704067200,
  FileSize:  1048576,
  Crc32:     0xDEADBEEF,
}
Schema Definition Example Values
[
  {
    "name": "timestamp",
    "type": "uint32",
    "endianness": "big_endian"
  },
  {
    "name": "file_size",
    "type": "uint32"
  },
  {
    "name": "crc32",
    "type": "uint32",
    "endianness": "little_endian"
  }
]
Message {
  timestamp: 1704067200,
  file_size: 1048576,
  crc32: 0xDEADBEEF,
}

uint64

64-bit Unsigned Integer

Fixed-width 64-bit unsigned integer (0-18446744073709551615). Respects endianness configuration.

Use for: High-precision timestamps, very large counters, database IDs, file offsets
Wire format: 8 bytes, byte order depends on endianness setting
Properties
Property Type Required Description
name string required Field name
type literal "uint64" required Field type (always 'uint64')
endianness enum ("big_endian" | "little_endian") optional Byte order for multi-byte values (big_endian or little_endian). Overrides global config if specified.
computed object optional Marks this field as automatically computed (e.g., length_of, crc32_of)
description string optional Human-readable description of this field
Generated Code
Type: bigint
  • JavaScript BigInt type (not Number!)
  • Number can only safely represent up to 2^53-1
  • Literal syntax: 123n
Type: uint64
  • Native Go uint64 type
Type: u64
  • Native Rust u64 type
Notes
  • Use for millisecond/microsecond timestamps
  • Exceeds JavaScript Number's safe integer range
Examples
Schema Definition Example Values
[
  {
    "name": "user_id",
    "type": "uint64"
  },
  {
    "name": "timestamp_ms",
    "type": "uint64",
    "endianness": "big_endian",
    "description": "Milliseconds since epoch"
  },
  {
    "name": "byte_offset",
    "type": "uint64"
  }
]
{
  user_id: 123456789012345n,  // BigInt literal!
  timestamp_ms: 1704067200000n,
  byte_offset: 0n
}
Schema Definition Example Values
[
  {
    "name": "user_id",
    "type": "uint64"
  },
  {
    "name": "timestamp_ms",
    "type": "uint64",
    "endianness": "big_endian",
    "description": "Milliseconds since epoch"
  },
  {
    "name": "byte_offset",
    "type": "uint64"
  }
]
Message{
  UserId:      123456789012345,
  TimestampMs: 1704067200000,
  ByteOffset:  0,
}
Schema Definition Example Values
[
  {
    "name": "user_id",
    "type": "uint64"
  },
  {
    "name": "timestamp_ms",
    "type": "uint64",
    "endianness": "big_endian",
    "description": "Milliseconds since epoch"
  },
  {
    "name": "byte_offset",
    "type": "uint64"
  }
]
Message {
  user_id: 123456789012345,
  timestamp_ms: 1704067200000,
  byte_offset: 0,
}

Signed Integers

int8

8-bit Signed Integer

Fixed-width 8-bit signed integer (-128 to 127). Single byte, no endianness concerns.

Use for: Small signed values, temperature readings, coordinate offsets
Wire format: 1 byte, two's complement encoding
Properties
Property Type Required Description
name string required Field name
type literal "int8" required Field type (always 'int8')
computed object optional Marks this field as automatically computed (e.g., length_of, crc32_of)
description string optional Human-readable description of this field
Generated Code
Type: number
  • JavaScript Number type
  • Safe for all int8 values
Type: int8
  • Native Go int8 type
Type: i8
  • Native Rust i8 type
Examples
[
  {
    "name": "temperature",
    "type": "int8",
    "description": "Temperature in Celsius"
  },
  {
    "name": "offset",
    "type": "int8"
  }
]

int16

16-bit Signed Integer

Fixed-width 16-bit signed integer (-32768 to 32767). Respects endianness configuration.

Use for: Signed coordinates, altitude values, timezone offsets
Wire format: 2 bytes, two's complement encoding, byte order depends on endianness
Properties
Property Type Required Description
name string required Field name
type literal "int16" required Field type (always 'int16')
endianness enum ("big_endian" | "little_endian") optional Byte order for multi-byte values (big_endian or little_endian). Overrides global config if specified.
computed object optional Marks this field as automatically computed (e.g., length_of, crc32_of)
description string optional Human-readable description of this field
Generated Code
Type: number
  • JavaScript Number type
  • Safe for all int16 values
Type: int16
  • Native Go int16 type
Type: i16
  • Native Rust i16 type
Examples
[
  {
    "name": "altitude",
    "type": "int16",
    "endianness": "big_endian"
  },
  {
    "name": "x_coord",
    "type": "int16"
  }
]

int32

32-bit Signed Integer

Fixed-width 32-bit signed integer (-2147483648 to 2147483647). Respects endianness configuration.

Use for: Large signed values, geographic coordinates, time differences
Wire format: 4 bytes, two's complement encoding, byte order depends on endianness
Properties
Property Type Required Description
name string required Field name
type literal "int32" required Field type (always 'int32')
endianness enum ("big_endian" | "little_endian") optional Byte order for multi-byte values (big_endian or little_endian). Overrides global config if specified.
computed object optional Marks this field as automatically computed (e.g., length_of, crc32_of)
description string optional Human-readable description of this field
Generated Code
Type: number
  • JavaScript Number type
  • Safe for all int32 values
Type: int32
  • Native Go int32 type
  • Also known as rune
Type: i32
  • Native Rust i32 type
Examples
[
  {
    "name": "latitude",
    "type": "int32",
    "endianness": "big_endian"
  },
  {
    "name": "time_delta",
    "type": "int32"
  }
]

int64

64-bit Signed Integer

Fixed-width 64-bit signed integer (-9223372036854775808 to 9223372036854775807). Respects endianness configuration.

Use for: High-precision signed timestamps, large signed offsets, financial calculations
Wire format: 8 bytes, two's complement encoding, byte order depends on endianness
Properties
Property Type Required Description
name string required Field name
type literal "int64" required Field type (always 'int64')
endianness enum ("big_endian" | "little_endian") optional Byte order for multi-byte values (big_endian or little_endian). Overrides global config if specified.
computed object optional Marks this field as automatically computed (e.g., length_of, crc32_of)
description string optional Human-readable description of this field
Generated Code
Type: bigint
  • JavaScript BigInt type (not Number!)
  • Number can only safely represent -(2^53-1) to (2^53-1)
  • Literal syntax: -123n
Type: int64
  • Native Go int64 type
Type: i64
  • Native Rust i64 type
Notes
  • Exceeds JavaScript Number's safe integer range
Examples
[
  {
    "name": "account_balance",
    "type": "int64",
    "description": "Balance in cents"
  },
  {
    "name": "time_offset_us",
    "type": "int64",
    "description": "Microsecond offset"
  }
]

Floating Point

float32

32-bit Floating Point

IEEE 754 single-precision floating point (32-bit). Provides ~7 decimal digits of precision.

Use for: Measurements, sensor data, graphics coordinates, scientific values
Wire format: 4 bytes, IEEE 754 format, byte order depends on endianness
Properties
Property Type Required Description
name string required Field name
type literal "float32" required Field type (always 'float32')
endianness enum ("big_endian" | "little_endian") optional Byte order for multi-byte values (big_endian or little_endian). Overrides global config if specified.
description string optional Human-readable description of this field
Generated Code
Type: number
  • JavaScript Number type
  • Stored internally as float64, but represents float32 wire value
Type: float32
  • Native Go float32 type
Type: f32
  • Native Rust f32 type
Notes
  • Range: ±1.4E-45 to ±3.4E38
  • Special values: NaN, +Infinity, -Infinity, -0
  • Not all decimal values can be represented exactly
Examples
[
  {
    "name": "temperature",
    "type": "float32",
    "endianness": "big_endian"
  },
  {
    "name": "sensor_value",
    "type": "float32"
  }
]

float64

64-bit Floating Point

IEEE 754 double-precision floating point (64-bit). Provides ~15 decimal digits of precision.

Use for: High-precision measurements, geographic coordinates, scientific calculations
Wire format: 8 bytes, IEEE 754 format, byte order depends on endianness
Properties
Property Type Required Description
name string required Field name
type literal "float64" required Field type (always 'float64')
endianness enum ("big_endian" | "little_endian") optional Byte order for multi-byte values (big_endian or little_endian). Overrides global config if specified.
description string optional Human-readable description of this field
Generated Code
Type: number
  • JavaScript Number type (native representation)
  • This is the default numeric type in JavaScript
Type: float64
  • Native Go float64 type
Type: f64
  • Native Rust f64 type
Notes
  • Range: ±5.0E-324 to ±1.7E308
  • Special values: NaN, +Infinity, -Infinity, -0
Examples
[
  {
    "name": "latitude",
    "type": "float64",
    "endianness": "big_endian"
  },
  {
    "name": "precise_measurement",
    "type": "float64"
  }
]

Complex Types

array

Array

Collection of elements of the same type. Supports fixed-length, length-prefixed, byte-length-prefixed, field-referenced, and null-terminated arrays.

Use for: Lists of items, message batches, repeated structures, variable-length data
data
T[N]
N × sizeof(T)
Properties
Property Type Required Description
name string required Field name
type literal "array" required Field type (always 'array')
kind enum ("fixed" | "length_prefixed" | "length_prefixed_items" | "byte_length_prefixed" | "null_terminated" | "signature_terminated" | "eof_terminated" | "field_referenced" | "variant_terminated" | "computed_count") required
items Array<string> required
Option 1:
  type string required
  description string optional Human-readable description of this field
length number (min: 0) optional
length_type enum ("uint8" | "uint16" | "uint32" | "uint64" | "varlength") optional
length_encoding enum ("der" | "leb128" | "ebml") optional
item_length_type enum ("uint8" | "uint16" | "uint32" | "uint64") optional
length_field string optional
count_expr string optional
terminator_value number optional
terminator_type enum ("uint8" | "uint16" | "uint32" | "uint64") optional
terminator_endianness enum ("big_endian" | "little_endian") optional
variants array optional
notes array optional
terminal_variants array optional
description string optional Human-readable description of this field
Generated Code
Type: Array<T>
  • JavaScript array
  • Elements type T depends on items field
Type: []T
  • Go slice
  • Elements type T depends on items field
Type: Vec<T>
  • Rust vector (heap-allocated)
  • Elements type T depends on items field
Notes
  • length_prefixed is most common for variable-length arrays
  • field_referenced allows dynamic sizing based on earlier fields
  • null_terminated useful for variable-length lists with terminator value
  • length_prefixed_items used when each item has individual length prefix (e.g., array of strings)
Examples
[
  {
    "name": "values",
    "type": "array",
    "kind": "fixed",
    "items": {
      "type": "uint32"
    },
    "length": 4
  },
  {
    "name": "items",
    "type": "array",
    "kind": "length_prefixed",
    "items": {
      "type": "uint64"
    },
    "length_type": "uint16"
  },
  {
    "name": "data",
    "type": "array",
    "kind": "field_referenced",
    "items": {
      "type": "uint8"
    },
    "length_field": "data_length"
  }
]

optional

Optional

Field that may or may not be present. Uses a presence indicator (byte or bit) followed by the value if present.

Use for: Optional data fields, nullable values, feature flags with associated data
Wire format: Presence indicator (1 byte or 1 bit) + value (if present=1)
Properties
Property Type Required Description
name string required Field name
type literal "optional" required Field type (always 'optional')
value_type union required
presence_type default required
description string optional Human-readable description of this field
Generated Code
Type: T | undefined
  • TypeScript union with undefined
  • Clean optional types
  • Type T depends on value_type field
Type: *T
  • Go pointer type (nil for absent)
  • Type T depends on value_type field
Type: Option<T>
  • Rust Option enum
  • Type T depends on value_type field
Notes
  • presence_type=uint8 uses 1 full byte (0=absent, 1=present)
  • presence_type=bit uses 1 bit (more compact for multiple optional fields)
  • Value is only encoded/decoded if presence indicator is 1
Examples
[
  {
    "name": "user_id",
    "type": "optional",
    "value_type": "uint64"
  },
  {
    "name": "nickname",
    "type": "optional",
    "value_type": "String",
    "presence_type": "uint8"
  },
  {
    "name": "flags",
    "type": "optional",
    "value_type": "uint8",
    "presence_type": "bit"
  }
]

discriminated_union

Discriminated Union

Type that can be one of several variants, chosen based on a discriminator value. Supports peek-based (read ahead) or field-based (reference earlier field) discrimination.

Use for: Protocol messages, polymorphic data, variant types, message envelopes
Wire format: Discriminator determines which variant type to parse. No additional type tag on wire (discriminator serves this purpose).
Properties
Property Type Required Description
name string required Field name
type literal "discriminated_union" required Field type (always 'discriminated_union')
discriminator union (enum ("uint8" | "uint16" | "uint32") | enum ("big_endian" | "little_endian") | string) required
Option 1:
  peek enum ("uint8" | "uint16" | "uint32") required Type of integer to peek (read without consuming bytes)
  endianness enum ("big_endian" | "little_endian") optional Byte order for uint16/uint32 (required for multi-byte types)
Option 2:
  field string required Name of earlier field to use as discriminator (supports dot notation like 'flags.type')
variants array (min length: 1) required
Array Element Fields:
  when string optional
  type string required
  description string optional Human-readable description of this field
byte_budget object optional Byte budget: limits variant decoding to the number of bytes specified by referenced field
description string optional Human-readable description of this field
Generated Code
Type: V1 | V2 | ...
  • TypeScript union of variant types
  • Requires type guards for access
  • Variant types depend on variants array
Type: interface{} (with type assertion)
  • Go interface with concrete variant types
  • Type assertion required for access
  • Variant types depend on variants array
Type: enum { V1(...), V2(...), ... }
  • Rust enum with named variants
  • Pattern matching for access
  • Variant types depend on variants array
Notes
  • Peek-based: Reads discriminator without consuming bytes (useful for tag-first protocols)
  • Field-based: Uses value from earlier field (useful for header-based protocols)
  • Each variant has a when condition (e.g., `value == 0x01`) that determines if it matches
  • Conditions support string literals (e.g., `value == 'SIZE'`) for matching ASCII chunk IDs
  • The last variant may omit when to act as a fallback/default for unrecognized discriminator values
  • byte_budget: Limits variant decoding to N bytes from a referenced numeric field. Creates a sub-slice for the variant decoder; main decoder advances by the full budget. Essential for RIFF/IFF-style chunk formats.
  • byte_budget pairs naturally with eof_terminated arrays in fallback variants — the sub-slice EOF boundary becomes the byte budget boundary
Examples
[
  {
    "name": "message",
    "type": "discriminated_union",
    "discriminator": {
      "peek": "uint8"
    },
    "variants": [
      {
        "when": "value == 0x01",
        "type": "QueryMessage"
      },
      {
        "when": "value == 0x02",
        "type": "ResponseMessage"
      }
    ]
  },
  {
    "name": "content",
    "type": "discriminated_union",
    "discriminator": {
      "field": "chunk_id"
    },
    "byte_budget": {
      "field": "content_size"
    },
    "variants": [
      {
        "when": "value == 'SIZE'",
        "type": "SizeData"
      },
      {
        "type": "RawBytes"
      }
    ]
  }
]

bitfield

Bitfield

Container for packing multiple bit-level fields into a compact byte-aligned structure. Allows precise bit-level control.

Use for: Flags, compact headers, protocol opcodes, bit-packed data
Wire format: Packed bits stored in bytes (size determines total bytes). Bit order (MSB/LSB first) determined by config.
Properties
Property Type Required Description
name string required Field name
type literal "bitfield" required Field type (always 'bitfield')
size number (min: 1) required
bit_order enum ("msb_first" | "lsb_first") optional
fields array required
Array Element Fields:
  name string required Field name
  offset number required
  size number required
  description string optional Human-readable description of this field
description string optional Human-readable description of this field
Generated Code
Type: object with number fields
  • TypeScript object with numeric properties
  • Each field is a number
  • Bit manipulation handled by encoder/decoder
Type: struct with uintN fields
  • Go struct with appropriate uint types
  • Bit manipulation handled by encoder/decoder
Type: struct with uN fields
  • Rust struct with appropriate uint types
  • Bit manipulation handled by encoder/decoder
Notes
  • Size must be multiple of 8 for byte alignment
  • Field offsets specify bit position within the bitfield
  • Bit order (MSB first vs LSB first) affects how bits are numbered
Examples
[
  {
    "name": "flags",
    "type": "bitfield",
    "size": 8
  }
]

back_reference

Back Reference

Backward reference to data at an earlier position in the message. Used for compression via backwards references (like DNS name compression). Offset is always from message start.

Use for: Message compression, duplicate data elimination, backwards references, deduplication
Wire format: Storage integer with offset bits (extracted via mask). Offset points backwards to earlier data in message (measured from message start).
Properties
Property Type Required Description
type literal "back_reference" required Type identifier (always 'back_reference')
storage enum ("uint8" | "uint16" | "uint32") required Integer type used to store the offset on the wire (uint8 = 1 byte, uint16 = 2 bytes, uint32 = 4 bytes)
offset_mask string (pattern: /^0x[0-9A-Fa-f]+$/) required Hex bitmask to extract offset bits from the storage integer (e.g., '0x3FFF' extracts lower 14 bits). Allows packing flags or type tags in unused bits.
offset_from enum ("message_start" | "current_position") required Reference point for offset calculation. 'message_start' = offset from beginning of message (byte 0), 'current_position' = relative offset from current read position
target_type string required Name of the type to parse at the referenced offset location. When decoder jumps to the offset, it will decode this type.
endianness enum ("big_endian" | "little_endian") optional Byte order for multi-byte storage types (required for uint16/uint32, meaningless for uint8)
description string optional Human-readable description of this back reference field
name string required Field name
Generated Code
Type: T (resolved value)
  • TypeScript uses resolved value, not pointer
  • Encoder handles deduplication
  • Type T depends on target_type field
Type: T (resolved value)
  • Go uses resolved value, not pointer
  • Encoder handles deduplication
  • Type T depends on target_type field
Type: T (resolved value)
  • Rust uses resolved value, not pointer
  • Encoder handles deduplication
  • Type T depends on target_type field
Notes
  • offset_mask extracts offset bits (allows packing flags in unused bits)
  • Offset is always measured from message start (backwards only)
  • Cannot reference data that comes later (no forward references)
  • Common in DNS (name compression) and other protocols with repeated data
Examples
[
  {
    "name": "domain_name_ref",
    "type": "back_reference",
    "storage": "uint16",
    "offset_mask": "0x3FFF",
    "target_type": "DomainName",
    "endianness": "big_endian",
    "description": "Compressed domain name (DNS-style)"
  }
]

Other Types

bool

Boolean

Boolean value encoded as a single byte. 0x00 = false, 0x01 = true.

Use for: Feature flags, enabled/disabled states, presence indicators
Wire format: 1 byte (0x00 or 0x01)
Properties
Property Type Required Description
name string required Field name
type literal "bool" required Field type (always 'bool')
description string optional Human-readable description of this field
Generated Code
Type: boolean
  • JavaScript boolean type
  • true/false
Type: bool
  • Native Go bool type
Type: bool
  • Native Rust bool type
Examples
Schema Definition Example Values
[
  {
    "name": "enabled",
    "type": "bool"
  },
  {
    "name": "visible",
    "type": "bool",
    "description": "Whether the item is visible"
  }
]
{
  enabled: true,
  visible: false,
}
Schema Definition Example Values
[
  {
    "name": "enabled",
    "type": "bool"
  },
  {
    "name": "visible",
    "type": "bool",
    "description": "Whether the item is visible"
  }
]
Flags{
  Enabled: true,
  Visible: false,
}
Schema Definition Example Values
[
  {
    "name": "enabled",
    "type": "bool"
  },
  {
    "name": "visible",
    "type": "bool",
    "description": "Whether the item is visible"
  }
]
Flags {
  enabled: true,
  visible: false,
}

bytes

Bytes

Raw byte array. Sugar for array of uint8 — same wire format, simpler schema definition.

Use for: Raw binary data, payloads, hashes, signatures, reserved bytes, binary blobs
Wire format: Depends on kind: fixed (N bytes), length_prefixed (length + bytes), field_referenced (length from earlier field)
Properties
Property Type Required Description
name string required Field name
type literal "bytes" required Field type (always 'bytes')
kind enum ("fixed" | "length_prefixed" | "length_prefixed_items" | "byte_length_prefixed" | "null_terminated" | "signature_terminated" | "eof_terminated" | "field_referenced" | "variant_terminated" | "computed_count") required
length number (min: 0) optional
length_type enum ("uint8" | "uint16" | "uint32" | "uint64" | "varlength") optional
length_encoding enum ("der" | "leb128" | "ebml") optional
length_field string optional
count_expr string optional
terminator_value number optional
terminator_type enum ("uint8" | "uint16" | "uint32" | "uint64") optional
terminator_endianness enum ("big_endian" | "little_endian") optional
terminal_variants array optional
description string optional Human-readable description of this field
Generated Code
Type: number[]
  • JavaScript number array
  • Each element is 0-255
Type: []byte
  • Go byte slice
Type: Vec<u8>
  • Rust byte vector
Examples
[
  {
    "name": "hash",
    "type": "bytes",
    "kind": "fixed",
    "length": 32
  },
  {
    "name": "payload",
    "type": "bytes",
    "kind": "length_prefixed",
    "length_type": "uint16"
  },
  {
    "name": "data",
    "type": "bytes",
    "kind": "field_referenced",
    "length_field": "data_length"
  }
]

choice

Choice

Flat discriminated union where the first field of each variant type serves as the discriminator. Each variant must have a const value on its first field for auto-detection during decoding.

Use for: Protocol sections with type tags, heterogeneous record types, tagged data blocks
Wire format: Discriminator is peeked (read without consuming) to determine which variant type to decode. Each variant includes the discriminator field in its wire format.
Properties
Property Type Required Description
type literal "choice" required Element type (always 'choice')
choices array (min length: 2) required List of possible types (must be at least 2)
Array Element Fields:
  type string required Name of the variant type
description string optional Human-readable description of this choice
name string required Field name
Notes
  • All variant types must have a first field with a const value (the discriminator)
  • All variant discriminator fields must have the same name and type
  • Discriminator values must be unique across all variants
  • Unlike discriminated_union, choice auto-detects the discriminator from the variant type definitions
Examples
[
  {
    "name": "data",
    "type": "choice",
    "choices": [
      {
        "type": "SparseFloor"
      },
      {
        "type": "DenseFloor"
      }
    ]
  }
]

conditional_field

Conditional Field

Field that is only present on the wire if a condition evaluates to true. Condition references earlier fields.

Use for: Protocol extensions, optional sections, feature-flagged data
Wire format: Field is only encoded/decoded if condition is true. No presence indicator on wire.
Properties
Property Type Required Description
name string required Field name
type string required
conditional string required
description string optional Human-readable description of this field
Generated Code
Type: T | undefined
  • TypeScript union with undefined
  • Undefined if condition false
  • Type T depends on type field
Type: *T or separate bool
  • Go pointer (nil if absent) or separate present flag
  • Type T depends on type field
Type: Option<T>
  • Rust Option enum
  • None if condition false
  • Type T depends on type field
Notes
  • Condition is evaluated during encoding/decoding
  • Supports dot notation for nested field access (e.g., 'header.flags.extended')
  • Unlike optional type, no presence indicator is stored on wire
Examples
[
  {
    "name": "extended_data",
    "type": "uint32",
    "conditional": "flags.has_extended == 1"
  },
  {
    "name": "metadata",
    "type": "Metadata",
    "conditional": "version >= 2"
  }
]

padding

Alignment Padding

Inserts zero bytes to align the current stream position to a byte boundary. Commonly used in binary formats like ELF, PE, PCF fonts, etc.

Use for: Structure alignment, section padding, word-aligned access
Wire format: 0 to (align_to - 1) zero bytes, depending on current position
Properties
Property Type Required Description
name string required Field name
type literal "padding" required Field type (always 'padding')
align_to number (min: 1) required Byte boundary to align to (must be power of 2: 2, 4, 8, etc.)
description string optional Human-readable description of this field
Generated Code
Type: void (not represented in value)
  • Padding is not stored in decoded value
  • Automatically calculated during encoding
Type: // not represented
  • Padding is handled internally
  • Not part of struct definition
Type: // not represented
  • Padding is handled internally
  • Not part of struct definition
Notes
  • Padding bytes are always zeros (0x00)
  • Number of padding bytes = (align_to - (position % align_to)) % align_to
  • If already aligned, zero bytes are inserted
  • Common values: 2 (word), 4 (dword), 8 (qword), 16 (paragraph)
Examples
[
  {
    "name": "padding",
    "type": "padding",
    "align_to": 4,
    "description": "Align to 4-byte boundary"
  },
  {
    "name": "section_padding",
    "type": "padding",
    "align_to": 8,
    "description": "Align to 8-byte boundary"
  }
]

varlength

Variable-Length Integer

Variable-length integer encoding that uses 1-N bytes depending on the value magnitude. Supports three encoding schemes: DER (ASN.1), LEB128 (protobuf), and EBML (Matroska/WebM).

Use for: Length fields in TLV protocols, space-efficient integer encoding, protocol buffer varints, EBML element IDs
Wire format: 1-N bytes depending on value and encoding scheme
Properties
Property Type Required Description
name string required Field name
type literal "varlength" required Field type (always 'varlength')
encoding enum ("der" | "leb128" | "ebml" | "vlq") required Variable-length encoding scheme: 'der' (ASN.1 length), 'leb128' (protobuf-style), or 'ebml' (Matroska-style)
max_bytes number (min: 1, max: 8) optional Maximum number of bytes for the encoded value (default: 4 for der, 5 for leb128, 8 for ebml)
computed object optional Marks this field as automatically computed (e.g., length_of)
description string optional Human-readable description of this field
Generated Code
Type: number | bigint
  • number for values up to 2^53-1
  • bigint for larger values
  • Encoding/decoding handled by runtime library
Type: uint64
  • Native Go uint64 type
  • Encoding/decoding methods provided by runtime
Type: u64
  • Native Rust u64 type
  • Encoding/decoding traits provided by runtime
Notes
  • DER encoding: 0x00-0x7F = short form (1 byte), 0x80+N = long form (1+N bytes)
  • LEB128 encoding: MSB continuation bit, little-endian, 7 bits per byte
  • EBML encoding: Leading zeros indicate width, self-synchronizing
  • Choose encoding based on protocol requirements, not personal preference
  • max_bytes limits maximum encoded size (default depends on encoding)
Examples
Schema Definition Example Values
[
  {
    "name": "content_length",
    "type": "varlength",
    "encoding": "der",
    "description": "ASN.1 DER length field"
  },
  {
    "name": "field_number",
    "type": "varlength",
    "encoding": "leb128",
    "description": "Protocol buffer field number"
  },
  {
    "name": "element_size",
    "type": "varlength",
    "encoding": "ebml",
    "description": "EBML element data size"
  }
]
{
  content_length: 500,      // DER: 0x81 0xC8 (2 bytes)
  field_number: 150,        // LEB128: 0x96 0x01 (2 bytes)
  element_size: 1024        // EBML: varies by width marker
}
Schema Definition Example Values
[
  {
    "name": "content_length",
    "type": "varlength",
    "encoding": "der",
    "description": "ASN.1 DER length field"
  },
  {
    "name": "field_number",
    "type": "varlength",
    "encoding": "leb128",
    "description": "Protocol buffer field number"
  },
  {
    "name": "element_size",
    "type": "varlength",
    "encoding": "ebml",
    "description": "EBML element data size"
  }
]
Message{
  ContentLength: 500,       // DER encoded
  FieldNumber:   150,       // LEB128 encoded
  ElementSize:   1024,      // EBML encoded
}
Schema Definition Example Values
[
  {
    "name": "content_length",
    "type": "varlength",
    "encoding": "der",
    "description": "ASN.1 DER length field"
  },
  {
    "name": "field_number",
    "type": "varlength",
    "encoding": "leb128",
    "description": "Protocol buffer field number"
  },
  {
    "name": "element_size",
    "type": "varlength",
    "encoding": "ebml",
    "description": "EBML element data size"
  }
]
Message {
  content_length: 500,      // DER encoded
  field_number: 150,        // LEB128 encoded
  element_size: 1024,       // EBML encoded
}