GCORM is a schema-first ORM toolkit for Go. It provides a Prisma-like schema language, a Go code generator, type-safe query builders, migration planning, and database tooling for PostgreSQL, MySQL, and SQLite.
The project is designed around generated Go code: define your data model in
.gcorm files, run the CLI, and use the generated client, query, and
model packages in your application.
- Schema-first data modeling with
.gcormfiles - Generated Go model structs and query helpers
- Type-safe CRUD builders for create, find, update, delete, bulk insert, upsert, aggregate, and group-by operations
- Parameterized SQL generation for normal user-provided values
- PostgreSQL, MySQL, and SQLite dialect support
- Migration diff generation with
up.sql,down.sql, and manifest files - Development utilities:
init,generate,fmt,validate,introspect,migrate, anddb push - Raw SQL escape hatches when you need full control
For full documentation, examples, and guides, visit the GCORM Wiki.
GCORM is early-stage software. The public APIs and schema language may still change. Review generated migrations before applying them to production databases.
- Go 1.26 or newer, matching this repository's
go.mod - A SQL driver for your database in your application, for example
pgx,go-sql-driver/mysql, ormodernc.org/sqlite
Install the CLI with:
go install github.com/arsfy/gcorm/cmd/gco@latestOr run it from a checkout:
go run ./cmd/gco helpCreate a schema file, for example schema/schema.gcorm:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "gco-go"
output = "./gen"
package = "db"
}
model User {
id String @id @default(uuid())
email String @unique
name String?
posts Post[]
createdAt DateTime @default(now())
@@map("users")
}
model Post {
id String @id @default(uuid())
title String
content String?
published Boolean @default(false)
authorId String
author User @relation(fields: [authorId], references: [id])
@@index([authorId])
}
Generate the Go client:
gco generate --schema schemaUse the generated packages:
package main
import (
"context"
"database/sql"
"os"
_ "github.com/jackc/pgx/v5/stdlib"
"your-module/gen/client"
"your-module/gen/query"
)
func main() {
ctx := context.Background()
db, err := sql.Open("pgx", os.Getenv("DATABASE_URL"))
if err != nil {
panic(err)
}
defer db.Close()
c := client.New(db, client.WithDialect("postgresql"))
defer c.Close()
users, err := c.User.Query().
Where(query.User.Email.Contains("@example.com")).
OrderBy(query.User.CreatedAt.Desc()).
Take(20).
Do(ctx)
if err != nil {
panic(err)
}
_ = users
}Usage:
gco <command> [flags]
Commands:
init Initialize a new GCORM schema interactively
generate Generate Go client code from schema
fmt Format schema files
validate Validate schema files
introspect Generate schema from existing database
migrate Manage database migrations
diff Generate migration from schema diff
dev Apply migrations in development mode
deploy Apply migrations in production mode
resolve Resolve migration state
db push Push schema changes directly to database
version Print version information
upgrade Upgrade gco when installed with go install
help Show this help message
Flags:
--schema <path> Path to schema directory or file
--config <path> Path to configuration file
gco upgrade checks GitHub releases and upgrades with the concrete latest
release tag:
go install github.com/arsfy/gcorm/cmd/gco@va.b.cThe upgrade command is limited to binaries installed with go install. If GCORM
was installed manually from a release archive, download and replace the binary
from GitHub Releases instead.
GCORM looks for gco.config.yaml or gco.config.yml in the current directory
and parent directories. You can also pass --config or set GCO_CONFIG.
Example:
schemaRoots:
- schema
migrationDir: migrations
format:
indentWidth: 2If no config is present, GCORM discovers schema files from schema/, prisma/,
or the current directory.
Create a migration from the current schema:
gco migrate diff --name init --schema schemaThe diff command creates a timestamped directory under migrations/ containing:
up.sqldown.sqlmanifest.json
Generate full initialization SQL for an empty database:
gco migrate init-sql --schema schema --output init.sqlDevelopment and deployment helpers are available:
gco migrate dev --name add_posts --schema schema
gco migrate deploy --dir migrations
gco migrate resolve --applied <migration_id>Review generated SQL before applying it, especially destructive changes and SQLite table rebuild scenarios.
Create a row:
user, err := c.User.Create().
Set(
query.User.Email.Set("ada@example.com"),
query.User.Name.Set("Ada"),
).
Do(ctx)Find rows:
users, err := c.User.Query().
Where(
query.User.Email.Contains("@example.com"),
query.User.Name.StartsWith("A"),
).
OrderBy(query.User.CreatedAt.Desc()).
Take(50).
Do(ctx)Update rows:
updated, err := c.User.Update().
Where(query.User.Email.Equals("ada@example.com")).
Set(query.User.Name.Set("Ada Lovelace")).
Do(ctx)Delete rows:
deleted, err := c.User.Delete().
Where(query.User.Email.Equals("ada@example.com")).
Do(ctx)Bulk insert:
count, err := c.Post.BulkCreate([]query.PostCreateInput{
{Id: "p1", Title: "First", Published: true, AuthorId: "u1"},
{Id: "p2", Title: "Second", Published: false, AuthorId: "u1"},
}).BatchSize(500).Do(ctx)Raw SQL:
rows, err := client.Raw[model.Post](
ctx,
c,
"SELECT id, title, published, author_id FROM posts WHERE author_id = $1",
"u1",
)Normal values passed through generated query helpers are sent as SQL parameters.
For example, Equals, In, Contains, StartsWith, EndsWith, and Set
do not concatenate user-provided values into SQL text.
String search helpers escape SQL LIKE wildcards so user input such as % and
_ is treated as literal text by default.
Raw SQL APIs and manually constructed clause structs are escape hatches. Treat them as trusted-code APIs and do not pass untrusted strings as SQL fragments, column names, operators, or function names.
Run the test suite:
go test ./...Run runtime query-builder benchmarks:
go test ./pkg/runtime/sqlbuilder -bench=. -benchmem -run=^$Run generated-client runtime benchmarks:
GCO_RUN_GENERATED_BENCH=1 go test -v ./pkg/codegen/golang \
-run TestGeneratedClientBulkCreateAndRawRuntime -count=1Release archive builds can inject the CLI version with Go linker flags:
go build -ldflags "-X main.Version=v0.1.0" ./cmd/gcoWhen installed with go install github.com/arsfy/gcorm/cmd/gco@v0.1.0, GCORM
uses Go build metadata to report the module version and allows gco upgrade to
upgrade the CLI through go install. Manually downloaded binaries should be
upgraded manually from GitHub Releases.
cmd/gco CLI entry point
pkg/schema Parser, formatter, validator, resolver, compiler
pkg/codegen/golang Go client generator
pkg/runtime Runtime interfaces, dialects, SQL builder, errors
pkg/tooling CLI tooling for generate, migrate, db push, fmt
examples Example schemas and usage
testdata Schema fixtures
GCORM is licensed under the MIT License. See LICENSE.