surformSurrealDB schemas, declared

What is Surform?

Like what you see here? Please consider hiring me.

Surform is a schema language for SurrealDB — a small, readable way to describe the tables, fields, indexes, events, and access rules your application needs, in one file you can read, review, and version like code.

The surform compiler turns that file into SurrealQL DDL — the DEFINE statements SurrealDB applies. And because a schema file drifts from the database it describes, Surform reads the database's INFO report back the same way: it compares what it finds with what you declared and tells you what changed.

A taste

applied to SurrealDB 3.3.0
schema.surdl
sdl
namespace acme;
database shop;

// Shared audit columns, spread into every table below.
mixin timestamped {
  field created_at: datetime { default: time::now(); };
  field updated_at: datetime;
};

/// A person in the company directory.
table person {
  schemafull;
  ...timestamped;
  field name: string;
  field email: string { assert: string::is_email($value); };
  index unique email_unique {
    fields: email;
  };
};
surform build
sql
DEFINE NAMESPACE OVERWRITE acme;
USE NS acme;
DEFINE DATABASE OVERWRITE shop;
USE NS acme DB shop;
DEFINE TABLE OVERWRITE person TYPE NORMAL SCHEMAFULL COMMENT 'A person in the company directory.';
DEFINE FIELD OVERWRITE created_at ON person TYPE datetime DEFAULT time::now();
DEFINE FIELD OVERWRITE updated_at ON person TYPE datetime;
DEFINE FIELD OVERWRITE name ON person TYPE string;
DEFINE FIELD OVERWRITE email ON person TYPE string ASSERT string::is_email($value);
DEFINE INDEX OVERWRITE email_unique ON person FIELDS email UNIQUE;

The first panel is the whole schema file. The second is what surform build prints — SurrealQL DDL, ready for any SurrealDB 3.3 tooling to apply.

The loop

Working with Surform is the infrastructure-as-code loop:

  1. Declare — describe the schema you want in schema.surdl.
  2. Check — surform check schema.surdl validates it and explains anything it doesn't understand, with a pointer at the line.
  3. Build & apply — surform build schema.surdl emits DDL. Run it through surreal sql, your SDK, or any migration runner. Every emitted DEFINE carries OVERWRITE (a credential-less user defines once), so applying again is safe: the database converges to the file.
  4. Converge — later, surform migrate generate schema.surdl --info … compares the file with the database's INFO output and prints both the drift and the script that converges the database to the file.

About the examples

Examples carry a badge saying how far each one ran — applied to SurrealDB 3.3.0, compiles clean, or shown for its diagnostics. The site is generated by running the tool, so the panels are its output; verification describes the pipeline.

What Surform covers

commandwhat it does
surform checkparse a schema file, report line-anchored diagnostics
surform buildemit the SurrealQL DDL
surform fmtprint (or rewrite) the file in the canonical style
surform normalizemerge the database's state back into the file — how you adopt an existing database
surform migrate generatewhat changed between file and database, plus the script that converges it
surform migrate commit / push / status / revertthe migration pipeline: hash and ledger-record a filled draft, apply committed migrations in number order, compare the directory against the live ledger, draft a revert
surform lintadvisory warnings — world-open tables, plaintext passwords, and other common traps

Where next

Start with Getting started — install the compiler and take the quick-start schema all the way to the database. Or read how a schema file works first. Editing in VS Code: the extension highlights .surdl files and formats them through the compiler. Coding agents: the repository carries an agent-harness skill, .agents/skills/surform/, that teaches the language and the CLI.