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.

unreal-orm

Type-safe SurrealDB queries with TypeScript without abstractions

Native First

Stays close to SurrealDB’s native capabilities, avoiding unnecessary abstractions that hide SurrealDB’s powerful features.

Type Safety

Full TypeScript type inference for your schema, queries, and results without runtime overhead.

Schema Generation

Generate valid SurrealDB schema definitions directly from your TypeScript code.

Query Builder

Type-safe query building with typed field proxies, IntelliSense, and full SurrealQL function coverage.

Graph Relations

Typed record links with automatic hydration via fetch, plus edge tables for many-to-many relationships.

CLI Tools

Manage schema with init, pull, push, diff, mermaid, and view commands.

AI Friendly

Includes dedicated llms.txt and llms-full.txt context files for a superior experience with LLMs and AI tools.

import { Surreal, surql } from 'surrealdb';
import { Table, Field, Index, Unreal } from 'unreal-orm';
// Define a User model with validation and custom methods
class User extends Table.normal({
name: 'user',
schemafull: true,
fields: {
name: Field.string(),
email: Field.string({ assert: surql`string::is::email($value)` }),
createdAt: Field.datetime({ default: surql`time::now()` }),
},
}) {
getDisplayName() {
return `${this.name} <${this.email}>`;
}
}
// Define a unique index
const userEmailIndex = Index.define(() => User, {
name: 'user_email_unique',
fields: ['email'],
unique: true,
});
// Define a Post with a relation to User
class Post extends Table.normal({
name: 'post',
schemafull: true,
fields: {
title: Field.string(),
content: Field.string(),
author: Field.record(() => User),
},
}) {}
async function main() {
const db = new Surreal();
await db.connect('ws://localhost:8000', {
namespace: 'test',
database: 'test',
authentication: { username: 'root', password: 'root' },
});
// Apply schema to database
await Unreal.applySchema(db, [User, userEmailIndex, Post]);
// Create records
const user = await User.create(db, {
name: 'Alice',
email: 'alice@example.com',
});
const post = await Post.create(db, {
title: 'Hello World',
content: 'My first post!',
author: user.id,
});
// Query with hydrated relations
const result = await Post.select(db, {
from: post.id,
only: true,
fetch: ['author'],
});
console.log(result.author.getDisplayName()); // "Alice <alice@example.com>"
}
main();