Data format
The DXN data format
DXN — Data eXchange Notation — is one data model written two ways: .dxn, a text form you can read and edit, and .dxnb, a binary form built on CBOR. Both carry the same 28 types, from exact decimals to sets, structs and timestamps, and convert into each other without loss.
A first look
A DXN document is a single value. This one is a map that uses most of the format at once:
@dxn "1.0"
%{
id: @uuid "550e8400-e29b-41d4-a716-446655440000"
name: "Ada Lovelace"
active: true
score: 19.99M
tags: @{:admin :staff}
meta: @ordered %{created: ~U[1990-01-01 00:00:00Z]}
address: %Point[51.05, 13.74]
result: {:ok, 200}
handle: ~r/^[a-z0-9_]{3,20}$/i
}@dxn "1.0"is an optional header naming the format version.%{…}is a map;name:is a keyword key. Commas are optional everywhere.19.99Mis an exact decimal, not a float — the type for money.@{…}is a set,{…}a tuple,@ordered %{…}a map whose order is part of its value.%Point[…]is a struct, written by position; a schema gives its fields names and types.@uuid,~U[…]and~r/…/are a UUID, a UTC timestamp and a regular expression — values of their own types, not strings.
The same document as .dxnb takes 215 bytes instead of 305, and decodes back to exactly the same value.
Design
- One model, two encodings. Every value has a text form and a binary form, and the round trip between them is lossless.
- Exact numbers. Integers have arbitrary precision; decimals and rationals are exact and stay that way in binary.
- Intent in the syntax. A tuple is not a list, an ordered map is not a map, a set is not a list without duplicates — the difference is written down, not agreed on the side.
- Graceful degradation. A struct or tag a reader knows nothing about still parses, into an opaque value it can pass on unchanged.
- Schemas in the same notation. A
.dxnsschema is a DXN document; there is no second language to learn. - Familiar to Elixir eyes. Maps, tuples, keywords, sigils and
?ccharacters are written the way Elixir writes them.
File facts
| Property | Value |
|---|---|
| Extensions | .dxn text, .dxnb binary, .dxns schema |
| Text encoding | UTF-8 |
| Text header | @dxn "1.0" — optional, first form only |
| Binary | DX, a version byte, then one CBOR item (RFC 8949) — see Binary format |
| Comments | # to the end of the line; text only |
| Grammar | PEG, written in Aether — see Grammar |
Implementations
These pages describe the format. The libraries below read and write it; each documents its own API.
| Name | Language | Role |
|---|---|---|
| dextrin | Elixir | The reference implementation: text, binary and schemas |
| node-dextrin | JavaScript | The same documents for Node.js |
| php-dextrin | PHP | The same documents for PHP |
| dextrin_html | Elixir | Converts between HTML and DXN |
| ichor | Elixir | The grammar compiler that generates dextrin’s text parser |
On these pages
- Text format — documents, separators, comments, identifiers, tags and discard.
- Values — all 28 types and how to write them.
- Binary format — the envelope, the CBOR mapping, private tags and value sharing.
- Schemas —
.dxnsdocuments: type expressions, struct schemas and enforcement. - Grammar — the formal grammar and where the reference implementation still differs from it.