Database
Forge accepts any database connection that satisfies the forge.DB interface — which *sql.DB and pgx adapters both implement. The driver is always your choice.
PostgreSQL — pgx via stdlib shim (recommended)
The recommended choice for most PostgreSQL users. One dependency, near-native pgx speed, compatible with all standard *sql.DB tooling.
go get github.com/jackc/pgx/v5import "github.com/jackc/pgx/v5/stdlib"
db := stdlib.OpenDB(connConfig) // *sql.DB backed by pgx
app := forge.New(forge.Config{DB: db, ...})PostgreSQL — native pgx pool (maximum performance)
For high-throughput production workloads. Uses forge-pgx, a thin adapter that is a separate module from Forge core (~2.5× faster than lib/pq).
go get forge-cms.dev/forge-pgx
go get github.com/jackc/pgx/v5import (
forgepgx "forge-cms.dev/forge-pgx"
"github.com/jackc/pgx/v5/pgxpool"
)
pool, _ := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
app := forge.New(forge.Config{DB: forgepgx.Wrap(pool), ...})SQLite
Zero external dependencies. Recommended for single-server deployments, prototyping, and personal sites. This is what forge-cms.dev runs on.
go get github.com/mattn/go-sqlite3import (
"database/sql"
_ "github.com/mattn/go-sqlite3"
)
db, _ := sql.Open("sqlite3", "./mysite.db")
app := forge.New(forge.Config{DB: db, ...})forge.Config. Nothing else in your codebase changes.SQLRepo — production SQL repository
SQLRepo[T] is the standard repository implementation backed by forge.DB. It derives the table name automatically or accepts an explicit override.
// Auto-derived table name: blog_posts
repo := forge.NewSQLRepo[*BlogPost](db)
// Explicit table name
repo := forge.NewSQLRepo[*BlogPost](db, forge.Table("posts"))
m := forge.NewModule((*BlogPost)(nil),
forge.At("/posts"),
forge.Repo(repo),
)SQLRepo uses $N positional placeholders and upserts via ON CONFLICT (id) DO UPDATE.
SeqRepository — streaming results
For large datasets, SQLRepo and MemoryRepo both implement SeqRepository[T] — a lazy streaming interface that avoids loading a full result set into memory.
if sr, ok := repo.(forge.SeqRepository[*Post]); ok {
for post, err := range sr.Seq(ctx, opts) {
// process one at a time
}
}