dsemakin/onyx

A portable interchange format for a personal food and body weight diary, and the engine that reads, validates and migrates it.

Rust

0

8 commits

updated Sep 12, 2026

See the code

See what people are saying (1)

README

Onyx

A portable interchange format for a personal food and body-weight diary, and the engine that reads, validates and migrates it.

CI Spec License

Why

There is no interchange format for a personal food diary. Every consumer calorie tracker exports a proprietary CSV and none of them import each other's. Open mHealth and IEEE 1752 cover body weight, activity and sleep across roughly 113 schemas and have no food schema at all. HL7 FHIR NutritionIntake was modelled on inpatient tray monitoring and no consumer app implements it. Apple Health has no food name field, so item identity is lost on export.

The result is that a person's own multi-year eating history is the least portable data they own — and "I have years of data in there" is the single most common reason people do not move between trackers.

Read the specification →

Status

The specification is at 1.0.0 and is implemented by one producer. This repository is building the reference engine; it is pre-release and the crates are not yet published. A second implementer is actively wanted — see GOVERNANCE.md.

Quick start

Validate a diary without installing anything:

npx @dsemakin/onyx validate diary.json

Or download the standalone onyx binary for your platform from the releases page — no runtime needed:

onyx validate diary.json

Use it as a library:

[dependencies]
onyx-core = { git = "https://github.com/dsemakin/onyx", tag = "v1.0.0" }

The crates are not on crates.io yet; that is a deliberate choice explained in docs/releasing.md.

Editor support

A document that carries the schema URL gets validation, autocomplete and hover documentation in VS Code and every JetBrains IDE with nothing installed:

{
  "$schema": "https://cdn.jsdelivr.net/gh/dsemakin/onyx@v1.0.0/spec/v1/log.schema.json",
  "format": "onyx",
  "specVersion": "1.0.0"
}

The reference engine writes that line into every document it produces. For files that lack it, VS Code can be told by file name, in settings.json:

"json.schemas": [
  { "fileMatch": ["*.onyx.json", "*.onx.json"],
    "url": "https://cdn.jsdelivr.net/gh/dsemakin/onyx@v1.0.0/spec/v1/log.schema.json" }
]

What is in here

PathContentsLicense
spec/The specification and versioned JSON SchemasCC0-1.0
corpus/Language-agnostic conformance suiteCC0-1.0
migrations/Declarative version-migration manifestsCC0-1.0
crates/Rust engine, CLI and wasm bindingsMIT OR Apache-2.0
packages/npm/The npx-able distributionMIT OR Apache-2.0
examples/Small reference readers in other languagesMIT OR Apache-2.0
docs/Architecture, conformance, releasingCC0-1.0
scripts/Repository checks; no build stepMIT OR Apache-2.0
.github/Contributing, security, governance, CI
LICENSES/Full licence texts, named by SPDX identifier

The first three directories are deliberately data, not code. Anyone can implement Onyx from them without reading a line of Rust, and the conformance corpus will tell them whether they got it right. That is the point: a format only one program can read is a backup, not a standard.

Dependencies

None. onyx-core depends on nothing; the CLI and the WebAssembly bindings depend only on onyx-core. The npm package has no dependencies and the workflows use one first-party GitHub Action.

The JSON reader, the error types, the argument parser and the WebAssembly ABI are all written here. That is a deliberate trade, argued in full — including what it costs — in docs/dependencies.md.

Implementations

ImplementationRoleConformance
BurninProducer, consumerCorpus pending
examples/reader-pyConsumerPasses all four groups

The Python reader is a reference example rather than an independent implementer — it proves the corpus is passable and the specification complete, not that anyone else has adopted the format.

One producer is not a format. If you have built a reader or a writer in any language, run the conformance corpus against it and open a pull request adding it here — that is the contribution this project wants most. A consumer that only reads its own files has implemented a backup.

Contributing

See CONTRIBUTING.md. Adding a conformance case requires no Rust at all; it is a JSON file in corpus/. If you are a coding agent, start with AGENTS.md.

Licensing

Code is dual-licensed under MIT or Apache-2.0 at your option, the Rust ecosystem convention. The specification, schemas, conformance corpus and migration manifests are released under CC0-1.0 — implement them freely, fork them, rename them. A standard that constrains its own adoption is not a standard.

Contributors

dsemakin

7 commits

dsemakin/onyx

A portable interchange format for a personal food and body weight diary, and the engine that reads, validates and migrates it.

Rust

0

8 commits

updated Sep 12, 2026

See the code

See what people are saying (1)

README

Onyx

A portable interchange format for a personal food and body-weight diary, and the engine that reads, validates and migrates it.

CI Spec License

Why

There is no interchange format for a personal food diary. Every consumer calorie tracker exports a proprietary CSV and none of them import each other's. Open mHealth and IEEE 1752 cover body weight, activity and sleep across roughly 113 schemas and have no food schema at all. HL7 FHIR NutritionIntake was modelled on inpatient tray monitoring and no consumer app implements it. Apple Health has no food name field, so item identity is lost on export.

The result is that a person's own multi-year eating history is the least portable data they own — and "I have years of data in there" is the single most common reason people do not move between trackers.

Read the specification →

Status

The specification is at 1.0.0 and is implemented by one producer. This repository is building the reference engine; it is pre-release and the crates are not yet published. A second implementer is actively wanted — see GOVERNANCE.md.

Quick start

Validate a diary without installing anything:

npx @dsemakin/onyx validate diary.json

Or download the standalone onyx binary for your platform from the releases page — no runtime needed:

onyx validate diary.json

Use it as a library:

[dependencies]
onyx-core = { git = "https://github.com/dsemakin/onyx", tag = "v1.0.0" }

The crates are not on crates.io yet; that is a deliberate choice explained in docs/releasing.md.

Editor support

A document that carries the schema URL gets validation, autocomplete and hover documentation in VS Code and every JetBrains IDE with nothing installed:

{
  "$schema": "https://cdn.jsdelivr.net/gh/dsemakin/onyx@v1.0.0/spec/v1/log.schema.json",
  "format": "onyx",
  "specVersion": "1.0.0"
}

The reference engine writes that line into every document it produces. For files that lack it, VS Code can be told by file name, in settings.json:

"json.schemas": [
  { "fileMatch": ["*.onyx.json", "*.onx.json"],
    "url": "https://cdn.jsdelivr.net/gh/dsemakin/onyx@v1.0.0/spec/v1/log.schema.json" }
]

What is in here

PathContentsLicense
spec/The specification and versioned JSON SchemasCC0-1.0
corpus/Language-agnostic conformance suiteCC0-1.0
migrations/Declarative version-migration manifestsCC0-1.0
crates/Rust engine, CLI and wasm bindingsMIT OR Apache-2.0
packages/npm/The npx-able distributionMIT OR Apache-2.0
examples/Small reference readers in other languagesMIT OR Apache-2.0
docs/Architecture, conformance, releasingCC0-1.0
scripts/Repository checks; no build stepMIT OR Apache-2.0
.github/Contributing, security, governance, CI
LICENSES/Full licence texts, named by SPDX identifier

The first three directories are deliberately data, not code. Anyone can implement Onyx from them without reading a line of Rust, and the conformance corpus will tell them whether they got it right. That is the point: a format only one program can read is a backup, not a standard.

Dependencies

None. onyx-core depends on nothing; the CLI and the WebAssembly bindings depend only on onyx-core. The npm package has no dependencies and the workflows use one first-party GitHub Action.

The JSON reader, the error types, the argument parser and the WebAssembly ABI are all written here. That is a deliberate trade, argued in full — including what it costs — in docs/dependencies.md.

Implementations

ImplementationRoleConformance
BurninProducer, consumerCorpus pending
examples/reader-pyConsumerPasses all four groups

The Python reader is a reference example rather than an independent implementer — it proves the corpus is passable and the specification complete, not that anyone else has adopted the format.

One producer is not a format. If you have built a reader or a writer in any language, run the conformance corpus against it and open a pull request adding it here — that is the contribution this project wants most. A consumer that only reads its own files has implemented a backup.

Contributing

See CONTRIBUTING.md. Adding a conformance case requires no Rust at all; it is a JSON file in corpus/. If you are a coding agent, start with AGENTS.md.

Licensing

Code is dual-licensed under MIT or Apache-2.0 at your option, the Rust ecosystem convention. The specification, schemas, conformance corpus and migration manifests are released under CC0-1.0 — implement them freely, fork them, rename them. A standard that constrains its own adoption is not a standard.

Contributors

dsemakin

7 commits

Languages

Rust

89.2%

JavaScript

10.1%