Reach for JSON when
Universal interoperability and standard ecosystem libraries are the primary requirement, and you don't need comments, custom validation, or symbolic data types.
comparison
SJON was designed for complex application state that is awkward to represent in JSON: hierarchically structured documents, nested configurations with inline expressions, and human-authored schemas that require rich syntax validation.
While JSON is the universal interchange format and EDN provides symbolic syntax, SJON is designed as an integrated substrate. It incorporates the layers that host applications typically have to implement on top of raw data: schema validation, comment-preserving round-trips, pure inline expressions, and a high-performance binary format.
/01 - JSON
JSON is optimized for machine-to-machine serialization. SJON is optimized for human-authored data files that require comments, structural validation, clear diagnostic errors, and domain-specific schemas.
| Area | JSON | SJON |
|---|---|---|
| Surface | Objects, arrays, strings, numbers, booleans, and null. | Forms, vectors, symbols, keywords, strings, booleans, nil, dates, times, and unit-bearing numbers. |
| Comments | No comments in standard RFC 8259 JSON. | Comments are captured as AST trivia. Preserved in lossless binary and printer paths, but discarded in canonical JSON/text. |
| Commas | Commas are required separators. Trailing commas are rejected in standard JSON. | Collections are whitespace-separated. Commas are illegal characters (invalid tokens) that raise syntax errors. |
| Keys | Object keys are strings. Duplicate-key behavior depends on parser and is often lossy/undefined. | Keys are :keyword-value pairs and are preserved in source order. Repeated keys are retained in the AST and flagged by schema validation. |
| Numbers | Stored as double-precision values, losing precision for large integers (> 2^53 - 1). | Integer literals stay exact up to 64-bit limits in the AST, but inline expression evaluation and some codecs cast them to f64. |
| Schema | No built-in schema layer; relies on external specifications (e.g., JSON Schema). | Validation is a core schema pass over the AST, with plugin-defined forms, slots, value kinds, and diagnostic spans. |
| Interop | Native serialization standard. | Semantic JSON bridge available. Canonical JSON normalizes form fields, discarding source order and trivia. |
/02 - EDN
EDN shares SJON's emphasis on Lisp-like symbols and keywords. However, SJON differs in extensibility and execution: instead of arbitrary reader tags, SJON features a strict, non-extensible syntax reader. Domain-specific extensions are handled entirely at the schema and validation layers, while safe expression evaluation is handled via a sandboxed interpreter.
| Area | EDN | SJON |
|---|---|---|
| Data model | Lists, vectors, maps, sets, symbols, keywords, and tagged literals. | Forms and vectors. No maps, sets, or lists. Forms use greedy :keyword pairing to represent key-value fields structurally. |
| Reader tags | Extensible via custom reader tags (`#my/tag value`), requiring reader configuration. | Syntax-closed. No reader tags or syntax extensions. All domain semantics are resolved at the schema validation layer. |
| Computation | Pure data representation; no built-in expression evaluation. | Includes a sandboxed, pure, and bounded interpreter (`evalExpr`) for safe inline calculations. |
| Strings | Double-quoted strings with standard backslash escapes. | Double-quoted strings plus raw triple-double-quoted strings (`"""…"""`) for literal payloads. |
| Numbers | Arbitrary precision numbers depend on reader and host platform support. | Integer literals are bounded to exact i64/u64; all other numeric paths default to f64. |
| Schema | Requires external validation frameworks (e.g., Clojure Spec). | Integrated schema and validator are first-class layers separate from bare parsing. |
| Host support | Mature and deeply integrated in Clojure; ecosystem support is highly uneven elsewhere. | Currently project-specific: Zig core with native host bindings for Node, Web, Rust, and TypeScript. |
/03 - numeric caveats
SJON supports exact 64-bit integers (i64/u64) in the parser and AST. However, float-shaped and unit-bearing numbers use double-precision floating-point (f64). Downstream expression evaluation and some plugin codecs also cast numbers to f64. The exact guarantees are detailed below.
/04 - choosing
These three formats overlap in surface and diverge in intent. The right choice follows the job in front of you, not a feature count.
Universal interoperability and standard ecosystem libraries are the primary requirement, and you don't need comments, custom validation, or symbolic data types.
You are working in a Clojure or Lisp ecosystem where native data structures like maps, sets, and custom reader tags are first-class citizens.
You are building tooling or configurations where human authors need robust schema validation with exact diagnostic spans, inline safe expressions, comment-preserving round-trips, and optional compact binary serialization.