Native First
Stays close to SurrealDB’s native capabilities, avoiding unnecessary abstractions that hide SurrealDB’s powerful features.
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 methodsclass 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 indexconst userEmailIndex = Index.define(() => User, { name: 'user_email_unique', fields: ['email'], unique: true,});
// Define a Post with a relation to Userclass 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();