Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RON

RON means Readable Object Notation.

This repository is the language-neutral reference for the RON format. RON keeps the JSON data model while making large JSON-shaped documents easier to write, easier to read, and cheaper in LLM tokens. It contains the format decision record, an implementation guide, and conformance fixtures for RON -> JSON and JSON -> RON, including pretty-format golden files.

This RON is not Rusty Object Notation.

RON borrows the readability goal of data-first expression syntaxes while keeping the JSON value model as the contract. See Expressions and related formats for comparisons with EDN and other adjacent syntaxes.

Documentation map

Use this order:

  • Orientation
    • Quick Start: read this before running conformance commands; compare RON with equivalent JSON.
  • Concepts
  • Reference
  • Ecosystem
    • Nix tooling: reproducible VS Code extension builds and a dev shell.
    • Implementations: current library support matrix.
    • vscode/: VS Code extension for RON syntax highlighting and Markdown fenced code blocks.
flowchart TD
  quick[Quick Start] --> formatting[Formatting modes]
  formatting --> escaping[String escapes]
  escaping --> expressions[Expressions]
  expressions --> typed[Typed vocabularies]
  typed --> reference[Reference]
  reference --> format[Format reference]
  reference --> vocab[Vocabulary reference]
  reference --> corpus[Test corpus]
  corpus --> implementations[Implementations]
Loading

Nix tooling

Build the VS Code extension VSIX from the repository root:

nix build .#vscode-extension-vsix

The VSIX is written to:

result/share/vscode/extensions/ron-language-0.1.1.vsix

Run flake checks:

nix flake check

Use the dev shell for local extension checks and packaging:

nix develop
cd vscode
npm run check
npm run package

Install the Nix-built extension locally:

code --install-extension result/share/vscode/extensions/ron-language-0.1.1.vsix

Quick Start

Start here before running the conformance commands. This example shows top-level object elision, nested objects, arrays, booleans, null, numbers, bare strings, quoted strings, quoted keys, optional commas, comma-prefixed tokens, and punctuation-like strings.

active true
age 37
commaPrefixed [,foo]
commaToken [, x]
commas {
  a 1,
  b 2,
}
emptyArray []
emptyObject {}
id ?id
metadata {
  count 9223372036854775808
  nullValue null
  score -12.5e+2
}
name Ada
quoted {
  double """a "quoted" phrase"""
  empty ''
  escapedLine a\nb
  literalBackslash a\\nb
  single 'Ada Lovelace'
  withApostrophe ''it's fine''
}
'quoted key' 'quoted value'
ref {# 200}
roles [admin writer]
strings [hello 'true' '123' '#_tmp']
temp #_tmp
{
  "active": true,
  "age": 37,
  "commaPrefixed": [
    ",foo"
  ],
  "commaToken": [
    ",",
    "x"
  ],
  "commas": {
    "a": 1,
    "b": 2
  },
  "emptyArray": [],
  "emptyObject": {},
  "id": "?id",
  "metadata": {
    "count": 9223372036854775808,
    "nullValue": null,
    "score": -12.5e+2
  },
  "name": "Ada",
  "quoted": {
    "double": "a \"quoted\" phrase",
    "empty": "",
    "escapedLine": "a\nb",
    "literalBackslash": "a\\nb",
    "single": "Ada Lovelace",
    "withApostrophe": "it's fine"
  },
  "quoted key": "quoted value",
  "ref": {
    "#": 200
  },
  "roles": [
    "admin",
    "writer"
  ],
  "strings": [
    "hello",
    "true",
    "123",
    "#_tmp"
  ],
  "temp": "#_tmp"
}

Formatting modes

RON formatting uses one output mode. Use an enum, string, or idiomatic equivalent:

  • pretty: multiline output. This is the default.
  • compact: single-line output.
  • canonical: canonical output for the selected target format.

pretty and compact preserve source/member order when it is available. They do not sort object keys. An implementation that receives an unordered host map must use and document a deterministic fallback order. That fallback is not source order or canonical output.

Canonical RON retains RON syntax and is compact. Canonical JSON is RFC 8785 JSON. Both apply the RFC 8785 and I-JSON contract. Canonical RON rejects duplicate decoded names, invalid Unicode, and Unicode noncharacters. RFC 7493 Section 2.1 applies to direct and escaped source text. It rejects source numbers when conversion to IEEE 754 double precision produces a non-finite value. Finite values can round during conversion. Canonical input parsing retains ordered object members and decoded names through duplicate-name validation. It does not collapse a base RON last-wins object first. Canonical RON uses ECMAScript number serialization and canonical RON string rendering. It uses recursive UTF-16 key order, compact UTF-8 output, and root-object brace elision. It does not preserve input number spelling.

Each ordinary case in testdata/conformance/manifest.json has explicit pretty, compact, and canonical JSON and RON output. The specialized testdata/rfc8785/ corpus contains primary RFC vectors, Appendix B numbers, and I-JSON rejection cases. Each canonical output has a SHA-256 value. The conformance manifest also adds RON-source-only canonical boundaries. Its formatting section declares pretty as the default mode.

Pretty JSON-to-RON rendering emits root JSON object members at top level by default. JSON-to-RON renderers should also expose typed value hooks for application-specific examples. Hooks map JSON values by path to replacement JSON values before RON formatting, so a string at tx can render as {# BE} by replacing it with {"#":"BE"}.

String escapes

Every RON string form uses JSON escapes, including bare strings, either quote style, repeated-delimiter strings, comma-prefixed strings, and object keys:

line a\nb
literalBackslash a\\nb
tab a\tb
recordSeparator \u001e
quoted 'a\nb'
embeddedJSON '{"coordinates":[12.5,-42.25],"type":"Point"}'
repeatedDouble """a "quoted" phrase"""

Backslash always introduces one of \", \\, \/, \b, \f, \n, \r, \t, or \uXXXX. Unknown or truncated escapes are invalid. Quoting controls token framing, not escape decoding. Inside an N-quote delimiter, same-quote runs shorter than N and every occurrence of the other quote byte are content; a same-quote run of at least N closes the string. Outside quoted strings, raw quotes remain structural. See docs/ADR.md for the normative rules.

Expressions and related formats

A RON expression is a JSON value written with lighter syntax: scalars, arrays, objects, top-level object members, and single-key tagged typed values. The model stays JSON-shaped so exact RON <-> JSON conversion remains the contract.

RON is not EDN or Clojure data notation. EDN helped prove that data-first expressions can be pleasant to author, but its native value model is wider than JSON and not a lowest-common-denominator interchange format across languages. RON keeps the readability goal and subtracts the non-JSON value space.

JSON5 and YAML solve adjacent authoring problems, but RON intentionally keeps a smaller JSON-compatible surface. See docs/ADR.md for the full alternatives analysis.

Typed vocabularies

Typed vocabularies are optional semantic layers over JSON-compatible single-key objects. Official vocabularies define readable tags such as #utc, #dur, #url, #uid, #rx, #dec, #set, #bits, #vN, #f3v, #geo, and #topo; custom vocabularies use namespaced tags such as #com.example/money. Base RON parsers preserve all of these as ordinary JSON objects.

Implementations

Implementation Language Base RON RFC 8785 canonical JSON
starfederation/ron-go Go Escape update required Yes
mbolli/php-ron PHP Escape update required Yes

Typed vocabulary support

Implementation Core Time Network Math Spatial Geo Color Custom
starfederation/ron-go
mbolli/php-ron

When adding an implementation, list each supported vocabulary URI or short name from docs/vocabularies.md, for example core, time, math, or geo. Use :white_check_mark: for supported vocabularies.

Conformance

Use testdata/conformance/manifest.json as the test runner input. For each valid case:

  1. Convert every ronInputs[] file to JSON.
  2. Compare pretty output with expectedPrettyJSON.
  3. Compare compact output with expectedCompactJSON.
  4. Compare canonical output with expectedCanonicalJSON and its SHA-256 hash.
  5. Convert jsonInput to RON.
  6. Compare pretty RON with expectedPrettyRON.
  7. Compare compact RON with expectedCompactRON.
  8. Compare canonical RON with expectedCanonicalRON and its SHA-256 hash.
  9. Parse generated RON back to JSON and compare JSON values, not text.
  10. Run jsonToRONRendering cases for root object elision and typed value hooks when those hooks are supported.

For invalid cases, every invalidRON[] file must fail RON parsing and every invalidJSON[] file must fail JSON -> RON conversion.

Use testdata/rfc8785/manifest.json for RFC 8785 canonical JSON and canonical RON vectors. Implementations must exact-match both byte forms, expected JSON UTF-8 hex, Appendix B number serialization samples, I-JSON rejection cases, and SHA-256 hashes.

Use testdata/vocabularies/manifest.json for typed vocabulary fixtures. Vocabulary-aware implementations should validate and map enabled typed tags; base implementations may treat the same files as ordinary JSON/RON round-trip cases.

About

Readable Object Notation

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages