unreal-orm
v1.0.0-alpha.9
Published
UnrealORM is a modern, type-safe ORM for SurrealDB that gives you native SurrealDB power, full TypeScript safety, and zero abstraction—no decorators, no magic, just classes and functions. Designed for developers who want direct control, advanced schema fe
Maintainers
Readme
UnrealORM
A modern, type-safe ORM for SurrealDB. Native SurrealDB power, full TypeScript safety, zero abstraction—no decorators, no magic, just classes and functions.
UnrealORM builds on top of the official surrealdb package, providing a TypeScript ORM experience while preserving full access to SurrealDB's native features. Define your schema once in code, and the ORM handles type inference, DDL generation, and schema synchronization.
Note: UnrealORM 1.0.0-alpha.x requires SurrealDB's 2.0 (alpha) JS SDK. If you're using 1.x of their SDK, install [email protected] instead. To upgrade, see the Migration Guide.
Quick Start
bunx @unreal-orm/cli init
# Or with other package managers
npx @unreal-orm/cli init
pnpm dlx @unreal-orm/cli init
yarn dlx @unreal-orm/cli initThis will:
- Set up your project structure (
unreal/folder) - Configure database connection (
surreal.ts) - Install dependencies (
unreal-orm,surrealdb,@unreal-orm/cli) - Optionally generate sample tables or import from existing database
# Using bun
bun add unreal-orm@latest surrealdb@alpha
bun add -D @unreal-orm/cli@latest
# Using pnpm
pnpm add unreal-orm@latest surrealdb@alpha
pnpm add -D @unreal-orm/cli@latest
# Using npm
npm install unreal-orm@latest surrealdb@alpha
npm install -D @unreal-orm/cli@latest
# Using yarn
yarn add unreal-orm@latest surrealdb@alpha
yarn add -D @unreal-orm/cli@latestFeatures
- Type-safe models — Define tables as classes with full TypeScript inference for fields, queries, and results
- Schema sync — Generate DDL from code with
applySchema(), or generate code from database withunreal pull - Relations — Typed record links with automatic hydration via
fetch - Native SurrealQL — Use
surqltemplates and functional expressions directly in queries and field definitions - Indexes — Define unique, composite, and search indexes with full type safety
- Custom methods — Add instance and static methods to your models
- CLI tools —
init,pull,push,diff,mermaidfor schema management
Example
import { Surreal, surql } from "surrealdb";
import Table, { Field, Index, applySchema } from "unreal-orm";
// Define a User model with validation and custom methods
class User extends Table.normal({
name: "user",
fields: {
name: Field.string(),
email: Field.string({ assert: surql`$value CONTAINS "@"` }),
createdAt: Field.datetime({ default: surql`time::now()` }),
},
}) {
getDisplayName() {
return `${this.name} <${this.email}>`;
}
}
// Define a unique index
const idx_user_email = Index.define(() => User, {
name: "idx_user_email",
fields: ["email"],
unique: true,
});
// Define a Post with a relation to User
class Post extends Table.normal({
name: "post",
fields: {
title: Field.string(),
content: Field.string(),
author: Field.record(() => User),
},
}) {}
async function main() {
const db = new Surreal();
await db.connect("ws://localhost:8000");
await db.signin({ username: "root", password: "root" });
await db.use({ namespace: "test", database: "test" });
// Apply schema to database
await applySchema(db, [User, idx_user_email, Post]);
// Create records
const user = await User.create(db, {
name: "Alice",
email: "[email protected]",
});
const post = await Post.create(db, {
title: "Hello",
content: "World",
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 <[email protected]>"
// Update with explicit mode
await user.update(db, { data: { name: "Alice Smith" }, mode: "merge" });
await db.close();
}See the Hands-on Tutorial for a complete walkthrough building a blog API with users, posts, comments, and relations.
Type-Safe Select
Select specific fields with full type inference:
import { typed } from "unreal-orm";
import { surql } from "surrealdb";
// Nested object fields - types inferred from objectSchema
const posts = await Post.select(db, {
select: { title: true, metadata: { category: true } },
});
// Type: { title: string; metadata: { category: string } }[]
// Nested record fields - types inferred from linked table
const posts = await Post.select(db, {
select: { title: true, author: { name: true, email: true } },
});
// Type: { title: string; author: { name: string; email: string } }[]
// Computed fields with typed() helper
const posts = await Post.select(db, {
select: { title: true, commentCount: typed<number>(surql`count(<-comment)`) },
});
// Type: { title: string; commentCount: number }[]
// Type-safe omit - exclude fields from result
const users = await User.select(db, {
omit: { password: true, secret: true },
});
// Type: Omit<User, 'password' | 'secret'>[]CLI
The CLI helps manage schema synchronization between your code and database:
unreal init # Initialize project with connection and sample tables
unreal pull # Generate TypeScript models from database schema
unreal push # Apply TypeScript schema to database
unreal diff # Compare code vs database schema
unreal mermaid # Generate ERD diagram
unreal view # Interactive TUI for browsing/editing records
unreal docs # Open the UnrealORM documentation
unreal github # Open the UnrealORM GitHub repositoryAfter init, the CLI is installed as a dev dependency and can be run via bunx unreal or npx unreal.
Documentation
- Getting Started — Installation and setup
- Hands-on Tutorial — Build a blog API step-by-step
- Capabilities — Supported SurrealDB features
- API Reference — Full API documentation
- Migration Guide — Upgrading from 0.x
Community
- 💬 GitHub Discussions — Questions & ideas
- 🐛 Issues — Bug reports
- 🤝 Contributing — How to contribute
- ⭐ Star on GitHub — Show support
- ☕ Ko-fi — Buy me a coffee
Author
UnrealORM is created and maintained by Jimpex.
