TSON (Typed Schema Object Notation) is simply a schema strategy pinch immutable, hash-pinned schemas whose definitions are themselves data. A archive names its schema, the schema names its meta-schema; one hash verifies the full chain. The finishing touch, TSON's information format is simply a Unicode-first superset of JSON you'll really bask writing.
TSON Data and Schemas documents stock the aforesaid lexer, aforesaid tooling, aforesaid verification. Schemas are maps pinch a compact grammar that's easy to publication and write. In this Schema, personification is simply a grounds pinch 2 fields; worker combines personification pinch section and level; the level section is an enum pinch a default; and each the fields are required by default.
Try it
Skip the reading. Run it.
There is simply a moving implementation: tson-java. The command-line tool's init-example bid writes you an illustration schema and a information archive pair. You tin usage the validate bid to spot really the information gets validated against the schema. Break the information (e.g. quote the age, delete a field) and it reports each problem astatine once, each pinch a way and a reason.
Get the implementation →
TSON Schema
A succinct schema built connected a coagulated foundation
Contracts you'd different scatter done validation code, stated successful declarations. The foundation: an eighteen-article investigation series knowing JSON and deriving what a schema is, from first principles, earlier immoderate syntax aliases codification was written.
§5.2
Records and section states
Fields are required by default. ~ supplies a default, = pins a value, ? makes the section optional. Five states, each 1 definitive successful the declaration.
schema
config => { host: text port: integer ~ 8080 retries: integer = 3 comment: text? }data
!config { host: "prod.db.internal" port: 5555 }§5.3
Arrays, tuples, sets
Sized homogeneous arrays, fixed-shape tuples, unique-membered sets. Three contracts that each publication arsenic 1 bracket syntax successful the data.
schema
tags => [text; 1..10] point => [number, number] badges => set<text>data (array, tuple and group each encode arsenic array)
!tags [urgent reviewed] !point [3.5 7.2] !badges [alpha beta]§5.5
Atoms and enums
Refine an atom's constraint vocabulary pinch ^, aliases mint a caller atom family pinch a constructor. The refinement IS-A its source; the enum is its ain family.
schema
port => !integer ^ { min: 1 max: 65535 } sku => !text ^ { pattern: "[A-Z]-[0-9]{3}" } rank => !enum [L1 L2 L3]data
!port 8080 !sku "A-123" !rank L2§5.8
Composition
New fields pinch declared ancestry: summons IS-A audit, and contributed section sets must beryllium disjoint. No silent overrides, nary gem ambiguity.
schema
audit => { created: datetime updated: datetime? } ticket => audit & { id: uuid title: text }data
!ticket { created: 2026-07-01T09:00:00Z id: 550e8400-e29b-41d4-a716-446655440000 title: "Server unreachable" }§5.7
Refinement
Tighten inherited fields without adding any: defaults tin move, pins can't, contracts only narrow. One modulation array governs each step.
schema
service => { host: text port: integer ~ 8080 } production => service ^ { port: = 443 }data (port fixed astatine 443; worth doesn't request repeating)
!production { host: "prod.internal" }§5.9
Subtraction
Removal is allowed, and loud: nationalist is not substitutable for account, and the resolved output records precisely that.
schema
account => { user: text email: text password: text } public => account - { password }§5.4
Choice
Sum types. Structurally disjoint variants request nary tag successful data; overlapping ones require one. The resolver derives which, per encoding.
schema
shape => (circle | rect) circle => { radius: number } rect => { width: number height: number } shapes => [shape; 1..5]data (type tag required for records)
!shapes [ !circle { radius: 4 } !rect { width: 2 height: 3 } ]§5.11
Field groups
Exactly-one-of, stated structurally: the information carries 1 personnel nether its ain label, and nary synthetic tag is invented.
schema
contact => { name: text ( email: email | phone: text ) }data (only telephone aliases email is allowed)
!contact { name: "Grace Hopper" phone: "555-0142" }§5.10
Templates
Definitions pinch blanks, complete type parameters and worth parameters both. A afloat bound exertion becomes a real, named type successful the resolved schema.
schema
paged => <T> { items: [T] cursor: text? } retry_policy => <N> { attempts: integer ~ N } checkout => retry_policy<5>data
!checkout { attempts: 10 }Schema Versioning
Adding a caller required section pinch ease
Version 2 conscionable added a caller required email section to the personification record. In mutable schema systems, adding a caller required section is universally forbidden. The API guidelines for Google, Microsoft and Zalando each prohibition the practice. Protobuf moreover marks the required keyword a hazard developers must avoid. These rules beryllium because a azygous meaning is forced to service each archive ever written against it. TSON removes this load because schemas are immutable. A type is simply a caller archive pinch a caller hash. Two contracts coexist astatine afloat strength, and worker composing personification inherits the caller request successful the aforesaid declaration.
Required intends required
Records stay wholly closed nether their type pinch nary fields near arbitrarily optional for future-proofing and nary tombstones carried forever.
Unknown fields are errors
Tolerating chartless fields is conscionable a workaround for in-place evolution. Without it a elemental typo triggers an contiguous correction alternatively of silently dropping data.
Route by version
The schema hash sits successful the header aliases connected the first statement for instant validation. A azygous server binds aggregate versions concurrently aliases a gateway routes requests to chopped backends.
Migration is simply a diff
Because some schemas are information a instrumentality computes the nonstop structural diff. Migrations go axenic transformations pinch mathematically precise input and output contracts.
The afloat versioning communicative →
TSON Data
A notation worthy reading
The schema strategy required a amended JSON, truthful it sewage a Unicode-first superset of JSON.
Same data, some sides.syntax JSON requiresmeaning TSON adds
§2.4
Quotes are optional
Identifiers and scalar values are unquoted tokens, defined complete Unicode identifier properties, truthful this useful successful each script, not conscionable ASCII. Quote only what needs quoting: spaces, colons, free text.
json
"city": "Melbourne", "имя": "Алиса"tson
city: Melbourne имя: Алиса§2.4
Commas are whitespace
Any whitespace separates items; commas still work, truthful JSON habits transportation over. Trailing commas stay errors successful both.
§7.6
Numbers you tin really write
Arbitrary precision, hex and binary, and digit separators resoluteness pinch nary note astatine all. Infinities and NaN are approximate-tier values and request an definitive !float64; rationals and analyzable numbers request their ain note too, since guidelines solution treats them arsenic strings otherwise.
json (closest you tin get)
"mask": 255, "budget": 1000000, "ratio": 3.142857142857143, "limit": "Infinity"tson
mask: 0xFF budget: 1_000_000 ratio: !rational "22/7" atoms: 6.02e23 limit: !float64 .inf gap: !float64 .nan§7.2.3
Strings pinch much than 1 line
Triple-quoted blocks pinch communal indentation stripped, truthful multi-line matter stays readable successful root and nonstop successful value.
json
"poem": "Roses are red\nViolets are blue"tson
poem: """ Roses are red Violets are blue """§2.6
Maps pinch existent keys
JSON objects unit each cardinal into a string. TSON keeps records (fixed named fields) and maps (variable associations) distinct, and representation keys tin beryllium immoderate value.
json (keys stringified)
{ "1": "one", "2026-03-13": "launch" }tson
{ 1 => one 2026-03-13 => launch }§2.9
Absent is not null
JSON gives 2 states (key missing, aliases null) to do 3 jobs. TSON's absent sentinel _ says "this position exists and holds nary value".
json (is this unset, unknown, aliases removed?)
"phone": nulltson
phone: _ scores: [1 _ 3 _ 5]§3.1
Metadata that travels pinch the value
Annotations connect ordered, preserved metadata to immoderate value: nary much "_comment" fields pretending to beryllium data. This is besides why TSON needs nary remark syntax: annotations past parsing.
json (the workaround)
"phone_comment": "deprecated, usage mobile", "phone": "555-0100"tson
phone: @deprecated:"use mobile" "555-0100"§5.1
Types erstwhile you want them
Type annotations tag a worth pinch what it is. A built-in vocabulary (dates, UUIDs, binary, precise numerics) useful pinch nary schema astatine all, and the worth parses to the autochthonal type, not a string.
json (strings that mean things)
"id": "550e8400-e29b-41d4-a716-446655440000", "price": 19.99tson
id: !uuid 550e8400-e29b-41d4-a716-446655440000 price: !number 19.99Compatibility
Every valid JSON archive is valid TSON.
TSON is simply a strict superset of JSON, pinch its 4 atomic types (null, boolean, number and string), positive UUIDs, dates, binary data, and arbitrary-precision numbers arsenic first-class values, parsed consecutive from quoted aliases unquoted text, nary schema required.
Current status
TSON is simply a working draft. The specification is published nether the 2026 revision bid and remains taxable to alteration until it freezes arsenic type 1. Implementations are underway: the first, a Java implementation, is already functioning. The meta-kernel, meta-schema, and halfway type room are already published pinch resolved fixtures, truthful parsers and resolvers will person reference answers to trial against. If the creation interests you, this is the shape wherever feedback shapes it.
What comes next
One schema. Multiple encodings.
The TSON Schema and its underlying type strategy are agnostic to the encoding; the aforesaid architecture arsenic ASN.1, wherever the schema is the merchandise and formats service it. The TSON matter information format is the first encoding, but won't beryllium the only one. The scheme is to create encoding rules for JSON, compact formats for illustration TOON, and binary, each carrying the aforesaid schema-verified values.
English (US) ·
Indonesian (ID) ·