Skip to content
🚀 This documentation is for unreal-orm 1.0.0 alpha which requires SurrealDB 2.0 SDK. For use with version 1.x, see here.

Capabilities

💎 Feature What it gives you
Schema-only mode Generate SurrealQL with generateFullSchemaQl() without touching the database—perfect for migrations & CI.
Embedded testing Run SurrealDB fully in-process via @surrealdb/node engines (mem://) for ultra-fast unit tests.
Parameterized queries (vars) Prevent injection; supported in select, count, query, etc.
Type-safe fetch projection Automatic hydration of related records (Field.record) with full TypeScript types.
Circular dependency thunk Use Field.record(() => OtherTable) to avoid import cycles while keeping types.
Advanced data types Full, type-safe support for bytes, duration, uuid, decimal, and specific geometry types.
Custom Surreal types Define Field.custom<'left' | 'right'>('"left" | "right"') or any other database type for ultimate flexibility.

Feature SurrealDB Syntax Example unreal-orm Support Notes
Basic Table Definition DEFINE TABLE user; Supported class User extends Table.normal({ name: 'user', ... })
IF NOT EXISTS DEFINE TABLE user IF NOT EXISTS; Supported Table.normal({ ..., method: 'IF NOT EXISTS' })
OVERWRITE DEFINE TABLE user OVERWRITE; Supported Table.normal({ ..., method: 'OVERWRITE' })
SCHEMAFULL DEFINE TABLE user SCHEMAFULL; Supported Table.normal({ ..., schemafull: true }) is the standard.
SCHEMALESS DEFINE TABLE user SCHEMALESS; Supported Table.normal({ ..., schemafull: false })
TYPE NORMAL DEFINE TABLE user TYPE NORMAL; Supported This is the default for Table.normal.
TYPE ANY DEFINE TABLE user TYPE ANY; Supported Not directly supported, use schemafull: false.
TYPE RELATION IN ... OUT ... DEFINE TABLE likes TYPE RELATION IN user OUT post; Supported Use Table.relation({ fields: { in: Field.record(...), out: Field.record(...) } }). ENFORCED not supported.
ENFORCED (for TYPE RELATION) DEFINE TABLE likes TYPE RELATION ... ENFORCED; Not Supported Tied to full TYPE RELATION syntax.
Table View (AS SELECT ...) DEFINE TABLE user_view AS SELECT ... FROM user; Supported class UserView extends Table.view({ name: 'user_view', as: surql'...' }).
CHANGEFEED @duration [INCLUDE ORIGINAL] DEFINE TABLE user CHANGEFEED 1h; Supported Table.normal({ ..., changefeed: { duration: '1h' } }).
PERMISSIONS (Table-level) DEFINE TABLE user PERMISSIONS FOR select WHERE ...; Supported Table.define({ ..., permissions: { select: '...' } })
COMMENT @string DEFINE TABLE user COMMENT 'User accounts'; Supported Table.define({ ..., comment: '...' })
DROP (within DEFINE TABLE) DEFINE TABLE user DROP; Not Supported REMOVE TABLE is a separate operation, not part of Table.define.
Feature SurrealDB Syntax Example unreal-orm Support Notes
Basic Field Definition DEFINE FIELD email ON user; Supported Via fields object in Table.define({ fields: { email: Field.string() } }).
IF NOT EXISTS (Field-level) DEFINE FIELD email ON user IF NOT EXISTS; Not Supported ORM regenerates the whole schema.
OVERWRITE (Field-level) DEFINE FIELD email ON user OVERWRITE; Not Supported ORM regenerates the whole schema.
TYPE @type (various types) DEFINE FIELD age ON user TYPE number; ⚠️ Partially See “Data Type Support” section below for detailed coverage.
FLEXIBLE TYPE @type DEFINE FIELD meta ON user FLEXIBLE TYPE object; Supported Use { flexible: true } with Field.object() or Field.custom(). Enables flexible schemas for object/custom fields.
DEFAULT @expression DEFINE FIELD role ON user TYPE string DEFAULT 'guest'; Supported Field.string({ default: surql“guest” }). Handles primitives, time::now(), functions expressed as SurrealQL.
DEFAULT ALWAYS @expression DEFINE FIELD updated_at ON user TYPE datetime DEFAULT ALWAYS time::now(); Not Supported Only standard DEFAULT is supported.
VALUE @expression DEFINE FIELD created_at ON user VALUE time::now(); Supported Field.string({ value: surqltime::now() }) or e.g. Field.string({ value: surqlstring::lowercase($value) })
VALUE <future> { @expression } DEFINE FIELD last_accessed ON user VALUE <future> { time::now() }; Not Supported Only standard VALUE is supported, not VALUE .
ASSERT @expression DEFINE FIELD email ON user ASSERT string::is::email($value); Supported Field.string({ assert: surqlstring::is::email($value) })
READONLY DEFINE FIELD id ON user READONLY; Supported Field.string({ readonly: true })
PERMISSIONS (Field-level) DEFINE FIELD email ON user PERMISSIONS FOR select WHERE...; Supported Field.string({ permissions: { ... } })
COMMENT @string DEFINE FIELD email ON user COMMENT 'User email'; Supported Field.string({ comment: '...' })
REFERENCE (with ON DELETE actions) DEFINE FIELD author ON post TYPE record<user> REFERENCE ON DELETE CASCADE; Supported Field.record(() => User, { reference: { onDelete: 'CASCADE' } }). (SurrealDB v2.2+)
Define type for id field DEFINE FIELD id ON user TYPE string; Supported Table.define({ fields: { id: Field.custom({ type: 'string' }) } })
Define types for specific array indices DEFINE FIELD data[0] ON mytable TYPE string; Not Supported Field.array(Field.string()) defines type for all items.
Feature SurrealDB Syntax Example unreal-orm Support Notes
Basic Index Definition DEFINE INDEX user_email ON user COLUMNS email; Supported Table.define({ indexes: { user_email: { fields: ['email'] } } })
IF NOT EXISTS (Index-level) DEFINE INDEX user_email ON user IF NOT EXISTS ...; Not Supported ORM regenerates the whole schema.
OVERWRITE (Index-level) DEFINE INDEX user_email ON user OVERWRITE ...; Not Supported ORM regenerates the whole schema.
UNIQUE Index DEFINE INDEX user_email ON user COLUMNS email UNIQUE; Supported Index.define(() => User, { fields: ['email'], unique: true })
SEARCH ANALYZER (Full-Text Search) DEFINE INDEX ... SEARCH ANALYZER ... BM25 HIGHLIGHTS; Supported Use the analyzer option in Index.define. Other keywords like BM25 are not exposed.
Vector Index (MTREE, HNSW) DEFINE INDEX ... MTREE DIMENSION ...; Not Supported
COMMENT @string DEFINE INDEX user_email ON user ... COMMENT '...'; Supported Use the comment option in Index.define.
CONCURRENTLY DEFINE INDEX user_email ON user ... CONCURRENTLY; Not Supported

unreal-orm primarily focuses on schema generation for tables, fields, and indexes. Other DEFINE statements are not yet supported by the ORM.

Feature SurrealDB Syntax Example unreal-orm Support Notes
DEFINE NAMESPACE DEFINE NAMESPACE test; Not Supported Operates within a given DB/NS connection.
DEFINE DATABASE DEFINE DATABASE test; Not Supported
DEFINE USER DEFINE USER ...; Not Supported
DEFINE TOKEN DEFINE TOKEN ...; Not Supported
DEFINE SCOPE DEFINE SCOPE ...; Not Supported
DEFINE ANALYZER DEFINE ANALYZER ...; Not Supported
DEFINE EVENT DEFINE EVENT ... ON TABLE ...; Not Supported
DEFINE FUNCTION DEFINE FUNCTION fn::abc() ...; Not Supported
DEFINE PARAM DEFINE PARAM $myparam ...; Not Supported
import { surql } from "surrealdb";
import { Table, Field } from "unreal-orm";
class User extends Table.normal({
name: "user",
schemafull: true,
fields: {
name: Field.string({ assert: surql`$value.length > 2` }),
age: Field.number({ assert: surql`$value >= 0`, default: surql`0` }),
isActive: Field.bool({ default: surql`true` }),
createdAt: Field.datetime({ default: surql`time::now()` }),
profile: Field.object({
bio: Field.string(),
website: Field.option(Field.string()),
}),
tags: Field.array(Field.string(), { max: 10 }),
posts: Field.array(Field.record(() => Post)),
nickname: Field.option(Field.string()),
// Advanced Types
balance: Field.decimal(),
apiKey: Field.uuid(),
lastLogin: Field.duration(),
avatar: Field.bytes(),
location: Field.geometry("point"),
side: Field.custom<"left" | "right">('"left" | "right"'),
},
}) {}
// Define indexes separately
const UserNameIndex = Index.define(() => User, {
name: "user_name_idx",
fields: ["name"],
unique: true,
});