Skip to content

Objects & Types

An Object is Lar’s unit of data — what you’d casually call “a note,” but typed. Every Object has:

  • Exactly one TypePerson, Project, Book, Daily Note, or one you define.
  • Typed properties, declared by its Type (text, number, date, select, checkbox, relation, …).
  • Typed relations to other Objects — including a system mentions relation auto-created whenever you write [[Title]].
  • Optionally, a body — rich block content, only if the Type declares hasBody: true.

Tag-based systems let you bolt metadata onto anything, but nothing stops two “Book” notes from having incompatible shapes. Lar’s Objects are always structurally valid for their Type — a query like type:Book prop.rating:>4 is guaranteed to mean the same thing for every Book Object, because the schema is enforced, not conventional.

Sometimes you need a one-off field that doesn’t belong in the Type’s schema. Lar supports loose properties: untyped, uninherited, and excluded from typed queries. They exist so the typed model never blocks you from just writing something down — but they’re deliberately second-class, so you’re nudged toward promoting real structure into the Type when it recurs.

Types change over time. Lar never destructively rewrites a schema:

  • Renames happen via an alias, so old queries and existing data keep resolving.
  • Removals mark a property deprecated rather than deleting it.
  • Type changes (e.g. string → number) run a per-Object coercion migration you trigger explicitly.

Next: Inheritance.