Grove

Configuration

Configure Grove via YAML files, environment variables, or programmatic options.

The Grove Forge extension supports multiple configuration sources with automatic merging. YAML configuration takes precedence, with programmatic options filling in gaps.

YAML Configuration

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 Fields

FieldYAML KeyTypeDefaultDescription
Driverdriverstring""Database driver name
DSNdsnstring""Connection string
DisableRoutesdisable_routesboolfalseSkip CRDT sync route registration
DisableMigratedisable_migrateboolfalseSkip automatic migrations
BasePathbase_pathstring"/sync"URL prefix for CRDT sync routes

Supported Driver Names

NameDriver ModuleDatabase
postgresgithub.com/xraph/grove/drivers/pgdriverPostgreSQL, CockroachDB, Neon, Supabase
sqlitegithub.com/xraph/grove/drivers/sqlitedriverSQLite
mysqlgithub.com/xraph/grove/drivers/mysqldriverMySQL, MariaDB
mongodbgithub.com/xraph/grove/drivers/mongodriverMongoDB
tursogithub.com/xraph/grove/drivers/tursodriverTurso (LibSQL)
clickhousegithub.com/xraph/grove/drivers/clickhousedriverClickHouse

Programmatic Options

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 Behavior

When both YAML and programmatic options are provided:

  1. Driver/DSN: YAML takes precedence. If YAML has no driver, programmatic values are used.
  2. Boolean flags: Programmatic true values are additive — if either source sets a flag to true, it stays true.
  3. BasePath: YAML takes precedence. Programmatic fills in if YAML is empty.
  4. 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:secret@db.example.com/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 programmatic

Require Config

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 Order

The extension resolves configuration in this order:

  1. YAML config: extensions.grove key → grove key
  2. Programmatic options: Values set via ExtOption functions
  3. Defaults: 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

On this page