A Prisma-like ORM for SurrealDB with schema-driven code generation and full TypeScript type safety.
Warning: Cerial is under active development and not yet ready for production use. APIs may change between releases. Use it for experimentation and side projects — production stability is coming soon.
- Schema-first — Define models in
.cerialfiles with a clean, readable syntax - Field types — String, Int, Float, Bool, Date, Email, Uuid, Duration, Decimal, Bytes, Geometry, Number, Any
- Embedded objects — Inline
object {}types with sub-field select, filtering, and updates - Tuples — Fixed-length typed arrays with
tuple {}blocks, named elements, and flexible input forms - Literal types — Union types with specific values, broad types, or structured variants
- Enums — String-only named constants with
enum {}, generatingas constobjects and union types - Typed IDs —
Record(int) @id,Record(uuid) @id, union types, and automatic FK type inference - Schema inheritance —
extendskeyword withabstractmodels,!!privatefields, and[pick/omit]selective inheritance - Arrays —
String[],Int[],Date[],Record[],ObjectType[]with query and update operators - Set arrays —
@setdecorator for auto-deduplicated, sorted arrays with@distinctand@sort - NONE vs null — Clean separation of absent fields (
?) from null values (@nullable) - Decorators —
@default,@defaultAlways,@createdAt,@updatedAt,@now,@readonly,@flexible,@unique,@index,@nullable,@uuid/@uuid4/@uuid7, geometry subtypes, and more - Composite directives —
@@indexand@@uniquefor multi-field constraints - Multi-schema — Multiple independent schema folders with per-schema client generation
- 1:1, 1:N, N:N — Full relation support with nested create, connect, and disconnect operations
- Self-referential — Models can relate to themselves (e.g.,
Userhasfriends: User[]) - Bidirectional sync — N:N relations keep both sides in sync automatically
- Cascade behavior —
@onDeletecontrols what happens when related records are removed
- Full CRUD —
findOne,findMany,findUnique,create,updateMany,updateUnique,deleteMany,deleteUnique - Upsert — Create-or-update with
upsertand conditional field logic - Aggregates —
count()andexists()for efficient record checks - Select & Include — Dynamic return types that narrow based on selected fields and included relations
- Pagination —
orderBy,limit, andoffsetfor result control - Return options —
updateUniqueanddeleteUniquesupportreturn: 'before',return: true(boolean), or default (after) - Unset — Explicit field clearing in updates with the
unsetparameter - Parameterized queries — All values bound via variables, safe from injection
- Lazy execution — Queries return a
CerialQueryPromisethenable, executing only onawait - Hooks —
onBeforeQuerycallback for query interception and logging - Introspection —
getMetadata(),getName(),getTableName()on every model
- Comparison —
eq,neq,not,gt,gte,lt,lte,between - String —
contains,startsWith,endsWith - Array —
in,notIn,has,hasAll,hasAny,isEmpty - Existence —
isNull,isDefined,isNone - Logical —
AND,OR,NOTcombinators - Nested — Filter through relations and into object sub-fields
- Array mode — Batch multiple queries with
$transaction([q1, q2]) - Callback mode — Managed transaction with model access via
$transaction(async (tx) => { ... }) - Manual mode — Explicit lifecycle with
commit()/cancel()andawait usingcleanup - Retry — Configurable retry count with optional backoff for conflict resolution
- Generated types — Full TypeScript types with IntelliSense from your schema
- Dynamic return types — Return types narrow based on
selectandinclude - Wrapper classes —
CerialId,CerialUuid,CerialDuration,CerialDecimal,CerialBytes,CerialGeometrywith rich APIs - Write-once fields —
@readonlyenforced at type level and runtime
- Code generation —
npx cerial generateproduces typed client from schema (bunxalso works) - Auto migrations — Schema changes generate SurrealQL
DEFINE TABLE/FIELD/INDEXstatements - Formatter — Auto-format
.cerialfiles with configurable style, column alignment, and comment preservation - Watch mode — Auto-regenerate on schema changes with per-schema isolation
- Configuration —
cerial.config.ts/cerial.config.jsonwithdefineConfig()helper - CLI init —
cerial initscaffolds config from detected schemas - Path filtering —
ignore/exclude/includeconfig fields with.cerialignoresupport
# npm
npm install cerial
# pnpm
pnpm add cerial
# yarn
yarn add cerial
# bun
bun add cerialNote: Marketplace publishing is not yet available. Install manually from a
.vsixfile.
Download the latest .vsix from the GitHub Releases page, then install via terminal:
code --install-extension path/to/cerial-0.1.0.vsixOr install through VS Code: Extensions panel (Ctrl+Shift+X) → ... menu → Install from VSIX...
See the installation guide for more options.
enum Role {
Admin
Editor
Viewer
}
model User {
id Record @id
email Email @unique
name String
age Int?
role Role @default(Viewer)
isActive Bool @default(true)
createdAt Date @createdAt
updatedAt Date @updatedAt
posts Relation[] @model(Post)
nicknames String[]
}
model Post {
id Record @id
title String
content String?
authorId Record
author Relation @field(authorId) @model(User)
createdAt Date @createdAt
}
npx cerial generate -s ./schemas -o ./db-clientOr use a config file:
// cerial.config.ts
import { defineConfig } from 'cerial';
export default defineConfig({
schema: './schemas',
output: './db-client',
});npx cerial generateimport { CerialClient } from './db-client';
const client = new CerialClient();
await client.connect({
url: 'http://localhost:8000',
namespace: 'main',
database: 'main',
auth: { username: 'root', password: 'root' },
});
// Create
const user = await client.User.create({
data: {
email: 'john@example.com',
name: 'John Doe',
isActive: true,
nicknames: ['Johnny'],
},
});
// Query with type-safe select
const users = await client.User.findMany({
where: { isActive: true, age: { gte: 18 } },
select: { id: true, name: true, email: true },
orderBy: { createdAt: 'desc' },
limit: 10,
});
// users: { id: CerialId; name: string; email: string }[]
// Include relations
const userWithPosts = await client.User.findOne({
where: { id: user.id },
include: {
posts: { limit: 5, orderBy: { createdAt: 'desc' } },
},
});
// userWithPosts: (User & { posts: Post[] }) | null
await client.disconnect();Full language support for .cerial schema files in VS Code and compatible editors.
- Syntax highlighting — Rich TextMate grammar with semantic tokens for all constructs
- IntelliSense — Context-aware completions for keywords, types, decorators, and cross-file references
- Diagnostics — Real-time parse errors and schema validation as you type
- Formatting — Format on save with 9 configurable style options
- Navigation — Go to Definition, Find All References, Rename Symbol across files
- Hover documentation — Type info, SurrealDB mappings, and decorator docs on hover
- Code actions — Quick fixes for common schema issues
- Inlay hints — Inferred FK types, behavior indicators, and inheritance sources
- Snippets — 16 code snippets for models, relations, decorators, and more
See the full extension documentation at cerial-orm.github.io/cerial/extension.
Planned features leveraging SurrealDB capabilities:
- Computed fields — Define derived values using SurrealDB expressions, calculated on-the-fly without storage
- Custom functions — Register reusable SurrealDB functions callable from queries
- Events — Define triggers that fire on record create, update, or delete
- Graph relations — Traverse relationships using SurrealDB's
->edge->graph syntax - Vector search — Store and query vector embeddings for AI/ML similarity search
- Full-text search — Search text fields with analyzers, tokenizers, and relevance scoring
- Geospatial queries — Distance calculations, containment checks, and intersection operators on Geometry fields
- Live queries — Real-time subscriptions that push record changes as they happen
- Field value expressions — Reference a field's incoming value in schema-level create/update expressions
- Previous value access — Access old field values during updates without a separate read query
Full documentation is available at cerial-orm.github.io/cerial:
- Getting Started — Installation, setup, first queries
- Schema — Field types, decorators, arrays, optionals, cross-file references
- Relations — 1:1, 1:N, N:N, self-referential, nested operations, delete behavior
- Queries — findOne, findMany, findUnique, create, upsert, update, delete, count, exists, $transaction
- Filtering — Comparison, string, array, logical, special, nested, object operators
- Select & Include — Dynamic return types, sub-field selection, nested includes
- Type System — CerialId, NONE vs null, generated types, dynamic return types
- CLI & Tooling — generate, init, config, formatter, watch mode, path filtering
- VS Code Extension — Features, settings, installation, snippets
- Release Notes — ORM and extension changelogs
This repository is a monorepo. The ORM package lives in apps/orm/ and the VS Code extension in apps/vscode-extension/.
This is a monorepo where packages share code across boundaries. After making changes, always verify both the ORM and extension build cleanly to catch breakage early:
# ORM
bun run orm:build
# Extension
bun run ext:build
bun run ext:dev:cursor # after that reload cursor windowApache 2.0 - See LICENSE for details.