Tutorial
any looks like a lot of machinery from the outside — types, properties, parts, datasets, modules, bundles, a catalog. Almost all of it is optional. In the simplest case you create an object and you are done; every further concept is one more thing you can add when you need it. This tutorial adds them in order, one part per level, with a working example at each step.
The four levels
1. Objects an object with a name and a description a notebook
2. Properties a type: typed columns on objects of that type a password manager
3. Datasets a table of records inside one object 10 000 emails
4. Apps parts, bundles, the sidebar, the catalog the mailbox as an app
Each level is complete on its own. A space full of plain objects with names is a valid space. A type with three properties and no parts is a valid type. You never have to reach the last level to use the first.
| Part | You build | You learn |
|---|---|---|
| 1. Objects | a notebook of named objects | create, read back, subscribe, rename, delete; the universal any group |
| 2. Properties | a password manager | types, the three ids, kinds and descriptors, choice options, filters on values, one object carrying several types |
| 3. Datasets | a mailbox holding 10 000 emails | a table inside one object: when to use it instead of many objects, an enforced schema, idempotent import, paging, search, aggregation |
| 4. Apps | the mailbox as a sidebar app | parts and modules, bundles that converge across devices, miniapp, the usecase catalog |
One model, two directions
Seen as a database, the simple things are objects, types and properties, and an app is the complicated construction on top. Seen from the interface, it flips: the simple thing is the app in the sidebar — a wiki, a chat, a contacts directory — and the objects, types and properties inside it are the details. any has to serve both. The levels above are the database direction; Part 4 ends where the interface begins, at the usecase catalog that installs the well-known apps with one call.
The picture to keep in mind
An object carries any number of types. Each type contributes its property definitions — the columns the object can hold values for — and its parts: display units a client renders, each owning a dataset that a module serves. The records module serves a dataset whose schema you declare; the editor module serves block documents; the chat module serves messages.
Attaching a type is the closest thing any has to inheritance, and it is deliberately flat. An object inherits columns and behaviour from every type it carries, side by side; types never inherit from each other. Part 4 spells out the rules, and you do not need them before then.
Why it matters. Every one of these levels is a CRDT record in an end-to-end encrypted space on your own device. A type definition, a choice option, a part declaration and the data they govern all sync the same way, so a schema change made offline on one device converges with data written on another without a migration step or a server that sees plaintext.
Before you start
The tutorial assumes a running server and one space, as in the Quickstart. Every example is a curl call against it:
API=http://127.0.0.1:7001/v1
SPACE=$(curl -s -X POST $API/spaces -H 'content-type: application/json' \
-d '{"name": "Tutorial"}' | jq -r .id)
Keep $SPACE — every part uses it.