Native syntax per database
A dual grove and bun tag system generates each database its own query shape. The hot path avoids reflection entirely, caching field offsets and pooling buffers to stay near raw driver speed.
An ORM that emits each database’s own dialect instead of a lowest common denominator: DISTINCT ON and JSONB operators on Postgres, ON DUPLICATE KEY UPDATE on MySQL, BSON aggregation pipelines on Mongo, PREWHERE and SAMPLE on ClickHouse. On the insert benchmark it runs about 9% over raw database/sql, against 111% for Bun and 156% for GORM.
Postgres, MySQL, SQLite, MongoDB, Turso, ClickHouse and Elasticsearch, each generating its own native syntax while sharing the registry and the hook engine.
Cached field offsets and pooled buffers, so the abstraction costs close to nothing once the query is built.
LWW-Register, PN-Counter and OR-Set converge without coordination, so distributed nodes can write independently.
PersistenceUses Grove for the data layer, with the migrations shipped by the Forge extensions that own them rather than kept in one central folder.
Shipping something on Grove? The list is only as complete as the people who tell me. Ask to be on it, or just say what got in your way.
Get listed →One ORM across seven databases, written so the abstraction does not become the cost.
A dual grove and bun tag system generates each database its own query shape. The hot path avoids reflection entirely, caching field offsets and pooling buffers to stay near raw driver speed.
LWW-Register, PN-Counter and OR-Set resolve their own conflicts, so nodes that were offline can merge when they return.
Redis, Memcached, DynamoDB, BoltDB and Badger behind composable middleware for logging, metrics and circuit breaking.
DBManager and Vessel resolve named connections, so Postgres, ClickHouse and SQLite can be live in one process with their own hooks and migrations.
Tenant isolation and PII redaction attach as hooks that run ahead of each query and mutation, which keeps authorisation logic out of the ORM itself.
Stream[T] pulls one row at a time, composes through Map, Filter, Chunk and Reduce, and works with range-over-func. ChangeStream adds change data capture on top.
Migrations are Go code ordered by what they depend on, so Forge extensions can ship their own and have them compose across modules.
Each generates native syntax while sharing the model registry, the hook engine and the migration ordering.
The reference driver. Everything else is measured against what this one does.
Native syntax generation with the same model registry and hooks.
The development and embedded target, and what the test suite runs against.
Document queries through the same builder the relational drivers use.
SQLite semantics over a replicated edge deployment.
Columnar reads for the analytical side of a mixed workload.
Search-shaped queries sharing the registry with the rest.
Key-value with keyspaces for logical separation.
Key-value where the cache is expected to be lossy.
Key-value against a managed store, behind the same middleware chain.
Embedded key-value in the process, with no network hop.
Embedded key-value tuned for write throughput.
Postgres, MySQL, SQLite, MongoDB, Turso and ClickHouse behind one API.
Modular, per-module, ordered by dependency.
Field-level rules applied at the store, not at the caller.
Large result sets read without loading them.
Grove is a polyglot Go ORM that generates each database's native query syntax rather than a portable subset. The common core handles connections, cached metadata, migrations, hooks and streaming; each driver exposes a builder that speaks its own dialect.
On the insert benchmark (SQLite in-memory, go1.25.7, darwin/arm64, five runs averaged):
The mechanism is that struct metadata is resolved once at registration and cached, so the query path walks a prepared description rather than the reflect API, with pooled buffers. Against a network round trip to a real database these differences are noise; they matter on bulk paths and inside Fabriq, where per-command overhead is multiplied by a fan-out.