Field methods

Every s.* field is chainable. This page is the complete list of methods. For how the $-clauses render, see from schema to DDL.

Two kinds of method: app-side and DDL

The methods split by prefix, and the prefix tells you which side a method acts on:

  • Non-$ methods are native Zod. s.* is a drop-in for z.*, so these behave exactly as in Zod — they shape the app-side value and its validation.
  • $-prefixed methods are Schemic’s. They attach a SurrealQL clause to the DEFINE FIELD — the database side.

The two do not bridge; each side is explicit. Where Zod and SurrealDB have a similar concept, there are two distinct methods:

App-side (native Zod, non-$)Database-side ($-prefixed)
.readonly() — TS-immutable output.$readonly() — SurrealDB READONLY
.describe() / .meta() — Zod metadata.$comment() — DDL COMMENT
.refine() / .check() — app-side validation.$assert() — DDL ASSERT

Native Zod methods

These delegate to the underlying Zod schema and act on the app side. They are available on any s.* field:

refine, superRefine, check, overwrite, transform, pipe, brand, readonly, describe, meta, plus optional, nullable, nullish, array, default, prefault, catch, loose, strict.

Two combinators build composite types:

MethodResultDDL TYPE
.or(other)uniona | b
.and(other)intersectionmerged object

Modifiers

These shape the field’s type. They carry through to both the TypeScript type and the DDL.

MethodDDL effectDescription
.optional()option<T>The field may be absent.
.nullable()T | nullThe field may be null.
.array()array<T>A list of the field’s type.
.loose()FLEXIBLEOn an object field, allow arbitrary extra keys.

SurrealQL clauses

Each $-method adds one clause to the field’s DEFINE FIELD. Expressions are written with the surql tag; $value refers to the field’s value.

MethodDDL clauseDescription
.$default(expr)DEFAULT exprValue applied on insert when the field is absent. Makes the field optional in the create shape.
.$defaultAlways()DEFAULT ALWAYSReapply the default on update as well as insert.
.$value(expr)VALUE exprAlways compute the stored value from the expression, overriding input.
.$computed(expr)COMPUTED exprA computed (read-only, derived) field.
.$assert(expr)ASSERT exprA constraint SurrealDB enforces on write.
.$readonly()READONLYAllowed on create, rejected on later change.
.$comment(text)COMMENT "text"Attach a comment to the field.
.$permissions(spec)PERMISSIONS FOR ... WHERE ...Per-operation access control (select, create, update).

Constraint helpers

These translate Zod-style constraints into SurrealQL ASSERT clauses.

MethodApplies toAsserts
.$min(n) / .$max(n)numberslower / upper bound
.$gt(n) / .$gte(n) / .$lt(n) / .$lte(n)numbersstrict / inclusive comparison
.$length(n)strings, arraysexact length
.$regex(re)stringspattern match

Indexing

MethodDDLDescription
.index()DEFINE INDEX ... FIELDS <field>A single-field index.
.unique()DEFINE INDEX ... UNIQUEA single-field unique index.

For composite indexes, use the table-level .index(name, fields, opts) — see definers.

Escape hatches

MethodDescription
.$surreal(type, codec)Set an explicit wire type and a custom { encode, decode } codec. See writing a custom codec.
.$internal()Mark the field internal: it exists on the table (so schemafull writes succeed) but grants no record-user access (PERMISSIONS NONE).

Where to go next