The Grove Forge extension supports multiple configuration sources with automatic merging. YAML configuration takes precedence, with programmatic options filling in gaps.
YAML Configuration01
Add a grove key under extensions in your Forge config file:
# config.yaml
extensions:
grove:
driver: postgres
dsn: "postgres://user:pass@localhost:5432/mydb"
disable_migrate: false
disable_routes: false
base_path: "/sync"The extension also supports a top-level grove key for backward compatibility:
# Legacy format
grove:
driver: postgres
dsn: "postgres://user:pass@localhost:5432/mydb"The namespaced extensions.grove key is checked first, then the top-level grove key.
Config Fields02
| Field | YAML Key | Type | Default | Description |
| Driver | driver | string | "" | Database driver name |
| DSN | dsn | string | "" | Connection string |
| DisableRoutes | disable_routes | bool | false | Skip CRDT sync route registration |
| DisableMigrate | disable_migrate | bool | false | Skip automatic migrations |
| BasePath | base_path | string | "/sync" | URL prefix for CRDT sync routes |
Supported Driver Names03
| Name | Driver Module | Database |
postgres | github.com/xraph/grove/drivers/pgdriver | PostgreSQL, CockroachDB, Neon, Supabase |
sqlite | github.com/xraph/grove/drivers/sqlitedriver | SQLite |
mysql | github.com/xraph/grove/drivers/mysqldriver | MySQL, MariaDB |
mongodb | github.com/xraph/grove/drivers/mongodriver | MongoDB |
turso | github.com/xraph/grove/drivers/tursodriver | Turso (LibSQL) |
clickhouse | github.com/xraph/grove/drivers/clickhousedriver | ClickHouse |
Programmatic Options04
Options set via ExtOption functions are merged with YAML configuration:
groveext.New(
groveext.WithDSN("postgres", dsn), // Driver + DSN
groveext.WithDriver(pgdb), // Pre-configured driver (takes precedence)
groveext.WithDisableMigrate(), // Disable auto-migration
groveext.WithDisableRoutes(), // Disable CRDT route registration
groveext.WithBasePath("/api/sync"), // Custom sync route prefix
groveext.WithRequireConfig(true), // Require YAML config
)Merge Behavior05
When both YAML and programmatic options are provided:
Driver/DSN: YAML takes precedence. If YAML has no driver, programmatic values are used.
Boolean flags: Programmatic
truevalues are additive — if either source sets a flag totrue, it staystrue.BasePath: YAML takes precedence. Programmatic fills in if YAML is empty.
WithDriver(): A pre-configured driver instance always takes precedence over YAML
driver+dsn.
Example: YAML + Programmatic
# config.yaml
extensions:
grove:
driver: postgres
dsn: "postgres://prod:[email protected]/myapp"// Programmatic options
app.Use(groveext.New(
groveext.WithDSN("sqlite", "file::memory:"), // Ignored — YAML takes precedence
groveext.WithDisableMigrate(), // Applied — YAML didn't set this
groveext.WithMigrations(appMigrations), // Applied — not a config field
groveext.WithHook(&auditHook), // Applied — not a config field
))
// Result: postgres driver from YAML + disable_migrate from programmaticRequire Config06
Use WithRequireConfig(true) to fail fast when no YAML config is found:
app.Use(groveext.New(
groveext.WithRequireConfig(true), // Error if no YAML config
))This is useful in production to ensure the application doesn't fall back to defaults.
Config Lookup Order07
The extension resolves configuration in this order:
YAML config:
extensions.grovekey →grovekeyProgrammatic options: Values set via
ExtOptionfunctionsDefaults: Empty config (no driver, no DSN)
If no config is found and no programmatic driver is set, the extension returns a clear error:
grove: no driver configured; use WithDriver() or set driver/dsn in config