---
title: "Aontu — A JSON structure unifier, for humans and agents"
description: "Aontu is JSON plus a lattice. Two documents do not override each other, they unify: the result is the most specific value that satisfies both, or an error naming the contradiction. That makes a definition checkable, queryable and safe to change."
source: "https://aontu.dev/"
---

# Configuration that _unifies_ instead of overwriting

Aontu is JSON plus a lattice. Two documents do not override each other, they **unify**: the result is the most specific value that satisfies both, or an error naming the contradiction. That makes a definition checkable, queryable and safe to change — by a person or by an agent.

[Start the tutorial](https://aontu.dev/docs/tutorial) [Read the docs](https://aontu.dev/docs)

## A schema, a default and data — in one notation

Every JSON document is an Aontu document. Then you add what JSON cannot say: that `port` must be an integer, that it defaults to `8080`, that `host` is a string. Unification combines all of it in one operation.

A conflicting fact — a second `port: "high"`, or a `port: 1.5` — is a precise error at the line that caused it, not a silent wrong answer.

config.aon

```
port:    *8080 | integer
host:    string
host:    "localhost"
```

aontu config.aon

```
{
  "host": "localhost",
  "port": 8080
}
```

## 13 verbs, in two implementations

The same command line ships in TypeScript and in Go, held to one language-agnostic test suite so the two cannot drift. Each verb answers as JSON with `--format json`, which is what makes the toolkit usable by something other than a person.

`vet`

does this data satisfy that truth?

`get`

what does it say at a path?

`why`

why does that value hold, and who set it?

`set`

change one value in an overlay, or in place

`subsume`

is this schema a widening of that one?

`breaking`

which changes break an earlier version?

`diff`

what changed between two documents?

`trim`

which entries are redundant?

`relations`

run the declared identity checks

`hash`

pin what a document means, not how it is spelled

`mod`

maintain a dependency closure

`reaches`

does one entity reach another, at any remove?

`jsonschema`

export the model, and name what the export cannot carry

Every flag and exit code is in the [API and CLI reference](https://aontu.dev/docs/reference-api). With no file, `aontu` starts a REPL.

**Not yet released.** The verbs ship in `0.53.0`. The newest published release is `aontu 0.52.1`, whose command line evaluates a file, prints canonical form and starts a REPL — and has none of the above. The documentation describes them because the engine does; installing from npm today does not get you them. Build from [source](https://github.com/aontu-lang/aontu) to use them now.

## Built for agents as much as for readers

An agent does not read a configuration by evaluating the whole thing into one blob. It holds identifiers, retrieves task-sized slices, asks why a value holds, and patches by path. Aontu answers each of those directly — and this site serves the same content as markdown at every URL, for anything that would rather not parse HTML.

-   ### Ask, don't evaluate

    `aontu get $.services.auth` retrieves one slice; `--keys` lists what exists; `why` names every contribution to a value and the line that wrote it.

-   ### A checkable contract

    `vet` branches its exit code — valid, invalid, incomplete, or the schema itself is unusable — so a repair loop knows which thing to fix.

-   ### An MCP server

    `aontu-mcp` runs locally over stdio and answers with the identical reports the CLI prints. No hosting, no key, no network.

-   ### A published grammar

    GBNF and Lark files ship in the package for constrained decoding, held by a test to accept every canonical form the suite produces.

## Install

npm

```
npm install aontu@0.52.1
```

Go

```
go install github.com/aontu-lang/aontu/go/cmd/aontu@latest
```

MIT licensed. Source, issues and the design record are on [GitHub](https://github.com/aontu-lang/aontu).
