A code-first database toolkit for SurrealDB. Define schemas, generate migrations, build queries, and perform typed CRUD -- all from Go.
- Code-First Migrations -- Schema changes defined in code with automatic migration generation (auto-diff +
.surqlfile output with-- @up/-- @downsections, squash, watcher, auto-snapshot hooks) - Type-Safe Query Builder -- Immutable fluent API with operator-typed
Where,SelectExpr/SelectAliasedaggregations, function factories, andencoding/jsonstruct tags - v3 Interactive Transactions -- Native
BEGIN/COMMIT/ROLLBACKviaDatabaseClient.Begin, plus raw record-id targets andGROUP ALL - Vector Search -- HNSW and MTREE index support with 8 distance metrics and EFC/M tuning
- Full-Text Search (BM25) -- the lexical leg of hybrid retrieval:
DEFINE ANALYZERin code (Analyzer/StandardAnalyzer), BM25-scoredFULLTEXTindexes (BM25Index), andQuery.FullTextSearch/Query.SearchScoreto query and rank - Graph Traversal -- Native SurrealDB graph features with edge relationships and a fluent
GraphQuerybuilder - Schema Visualization -- Mermaid, GraphViz, and ASCII diagrams with theming
- Full CLI --
surql migrate/schema/db/orchestratesubcommands for the entire lifecycle - Cache + Orchestration -- Memory + Redis cache backends, sequential / parallel / rolling / canary deployment strategies
go get github.com/Oneiriq/surql-goWith the CLI:
go install github.com/Oneiriq/surql-go/cmd/surql@latestpackage main
import (
"github.com/Oneiriq/surql-go/pkg/surql/schema"
)
func main() {
user, _ := schema.NewTableDefinition(
"user",
schema.WithMode(schema.TableModeSchemafull),
schema.WithFields(
schema.StringField("name"),
schema.StringField("email").WithAssertion("string::is::email($value)"),
schema.IntField("age").WithAssertion("$value >= 0 AND $value <= 150"),
schema.DatetimeField("created_at").WithDefault("time::now()").WithReadonly(true),
),
schema.WithIndexes(schema.UniqueIndex("email_idx", []string{"email"})),
)
_ = user
}import (
"github.com/Oneiriq/surql-go/pkg/surql/query"
"github.com/Oneiriq/surql-go/pkg/surql/types"
)
target := types.TypeRecord("user", "alice")
record, err := query.GetByTarget(ctx, client, target)opts := query.AggregateOpts{
Table: "match",
Select: map[string]types.Operator{
"count": query.CountAll(),
"avg": query.MathMean("score"),
},
GroupAll: true,
}
rows, _ := query.AggregateRecords(ctx, client, opts)import "github.com/Oneiriq/surql-go/pkg/surql"
raw, _ := client.Query(ctx, "SELECT count() AS n FROM user GROUP ALL")
count, _ := surql.ExtractScalar[int64](raw, "n")tx, _ := client.Begin(ctx)
if _, err := tx.Execute(ctx, "UPDATE user:alice SET status = 'active'"); err != nil {
_ = tx.Rollback(ctx)
return err
}
return tx.Commit(ctx)Full documentation at oneiriq.github.io/surql-go.
Key pages:
ConnectionConfig.DBURL accepts all URL schemes the upstream
surrealdb.go SDK parses, but
only the remote transports can actually open a connection. Embedded schemes
are parsed (so protocol detection still works) and then rejected at
DatabaseClient.Connect with ErrConnection pending upstream support.
| Scheme | Status | Notes |
|---|---|---|
ws:// |
Supported | WebSocket. Full feature set including live queries. |
wss:// |
Supported | TLS WebSocket. Full feature set including live queries. |
http:// |
Supported | HTTP RPC. No live queries. |
https:// |
Supported | TLS HTTP RPC. No live queries. |
memory:// |
Not yet | Parsed; Connect returns ErrConnection. Blocked by upstream surrealdb.go#197. |
mem:// |
Not yet | Alias of memory://. |
file:// |
Not yet | Parsed; Connect returns ErrConnection. Blocked by upstream surrealdb.go#197. |
surrealkv:// |
Not yet | Parsed; Connect returns ErrConnection. Blocked by upstream surrealdb.go#197. |
Use connection.Protocol.IsSupported() to check programmatically whether
a configured URL can open. The library will re-enable embedded schemes
automatically as soon as the SDK ships an embedded engine -- callers will
not need to change any code.
Downstream consumers that need an offline / embedded store today (for example kushtaka-cli's local cache) should keep their file-based fallback until upstream lands.
- Go 1.26+
- SurrealDB 3.0+ (CI runs against
surrealdb/surrealdb:v3.0.5)
Apache License 2.0 - see LICENSE.
- Python: surql-py -- the original, reference implementation (Python 3.12+).
- TypeScript / Deno / Node.js: surql -- type-safe query builder and client.
- Rust: surql-rs -- Rust port of this library, sharing the same schema + migration model.
- Documentation: oneiriq.github.io/surql-go
- Issues: GitHub Issues
- Changelog: CHANGELOG.md