Schemas Overview
What is a schema?
Section titled “What is a schema?”A schema is a TypeScript definition that describes the shape of your data. Every node in xNet conforms to a schema.
import { defineSchema, text, select, date } from '@xnet/data'
export const TaskSchema = defineSchema({ name: 'Task', namespace: 'xnet://my-app/', properties: { title: text({ required: true }), status: select({ options: [ { id: 'todo', name: 'To Do' }, { id: 'done', name: 'Done' } ] as const }), dueDate: date({ includeTime: true }) }})This gives you:
- Type safety —
task.statusis'todo' | 'done', notstring - Validation — required fields are enforced, values are range-checked
- Identity — the schema has a unique IRI:
xnet://my-app/Task - Coercion — values are normalized on creation (trimming, type conversion)
Schemas are the source of truth
Section titled “Schemas are the source of truth”The type inference flows from schema definition through every hook:
defineSchema({ properties: { title: text(), ... } }) ↓useQuery(TaskSchema) → { data: { id, title, ... }[] }useMutate().create(TaskSchema, { title: '...' })useNode(TaskSchema, id) → { data: { id, title, ... } }You define types once. Every hook infers from the schema.
Schema anatomy
Section titled “Schema anatomy”Every schema has:
| Field | Required | Description |
|---|---|---|
name | Yes | Display name (e.g., 'Task', 'Page'). |
namespace | Yes | Must match `xnet://${string}/`. Groups related schemas. |
properties | Yes | Record of property builders (e.g., text(), select()). |
extends | No | Parent schema to inherit properties from. |
document | No | CRDT document type: 'yjs' for rich text editing. |
The schema IRI is computed as ${namespace}${name} — e.g., xnet://my-app/Task.
Next steps
Section titled “Next steps” defineSchema Full reference for creating schemas.
Property Types All 16 property types with examples.
Relations Link nodes together with references.
Type Inference How TypeScript types flow from schemas.