I finally wrote the material I kept telling people I’d get around to. Omnist now has a proper introduction deck and a hands-on tutorial. The deck is language-agnostic — it explains the spec itself, not any one port’s API. The tutorial uses Python to walk through every model and feature with real, working code.

Why a deck and a tutorial, not just docs

The specification is precise on purpose. Precise documents are a bad place to start. You shouldn’t have to read a spec before you know if something is worth your time. The deck is the fifteen-minute version: what problem Omnist solves, and why the model looks the way it does. The tutorial is for someone who’s already decided to try it. Every example is real, working code, checked and run before it went in the page. It’s built as steps, so you can do them out of order once you know your way around.

The part that’s actually new: a decidable schema algebra

Most schema tools — JSON Schema, Avro, Protobuf — check one document against one schema at a time. Whether a schema change is safe is left to you: read the diff, guess, hope your tests catch it. Omnist treats that as a question with a real answer, not a judgment call:

  • compatible_with(A, B)true if every document B accepts, A also accepts.
  • equivalent(A, B)true if A and B accept exactly the same set of documents.
  • normalize(S) → the minimal schema that accepts the same set of documents as S.

These aren’t heuristics. They’re decidable, because Omnist’s schema model is deliberately closed. There are no open-ended union types, no escape hatches that would make the question unanswerable in general. That same closed model is why Omnist can extract a subschema from a larger one, or infer a schema from example documents, and get a deterministic answer both times.

The document model underneath is built the same way. Every node is an ordered list of (label, value) edges, not a map. That one choice is what lets Omnist read and write JSON, YAML, TOML, and XML into a single canonical form. Converting between any of those formats falls out of the model for free — no bespoke code path per pair.

Five ports, one spec

Omnist now runs natively in five languages, all built against the same specification:

I wrote about how that happened in Five Languages, One Law — why building two of the five ports from the spec alone, with no reference to the other code, was the real test of whether the spec was any good. That post is about how the ports got built. This one is about what to do now that they exist: read the deck, work through the tutorial, then pick a port and keep going.

If you try the tutorial and something’s unclear, or you find a case the deck doesn’t cover, I’d like to hear about it. Find me on X (@lee_tom) or LinkedIn.