How to Set Up Grok2API for Local Development with SQLite

Grok2API supports SQLite via a thin GORM abstraction layer, requiring only a configuration change to driver: sqlite in config.yaml to run locally without external dependencies.

Grok2API is an open-source API implementation that wraps GORM to support both SQLite for development and PostgreSQL for production. Setting up the SQLite backend requires no code changes—only configuration adjustments to use the pure-Go SQLite driver. This guide walks through the exact steps to configure the database layer as implemented in the chenyme/grok2api repository.

Prerequisites

Before configuring SQLite, ensure your environment meets the following requirements:

  • Go toolchain version 1.22 or higher
  • Make utility (the repository includes a Makefile for build automation)
  • A local clone of the chenyme/grok2api repository

No Docker container is required for a pure-SQLite development environment, though the repository ships with a docker-compose.yml for testing PostgreSQL production configurations.

Configuration

The database driver is controlled through the config.yaml file. Copy the provided example configuration and modify the database section:

cp config.example.yaml config.yaml

Edit config.yaml to specify SQLite as the driver:

database:
  driver: sqlite                # ← switch to sqlite

  sqlite:
    path: ./data/grok2api.db   # Relative path where the DB file will be created

    # max_connections and max_idle are optional

    max_connections: 16
    max_idle: 16

The configuration file is loaded and validated by backend/internal/infra/config/config.go, which enforces that the driver field must be either sqlite or postgres.

Database Initialization

When driver is set to sqlite, the database.NewDatabase factory in backend/internal/infra/persistence/relational/database.go loads the glebarez/sqlite driver—a pure-Go implementation that eliminates CGO dependencies.

The initialization logic branches specifically for SQLite:

import glebarezsqlite "github.com/glebarez/sqlite"

// In backend/internal/infra/persistence/relational/database.go
db, err := gorm.Open(glebarezsqlite.Open(dsn), gormConfig())
return configureDatabase(ctx, db, "sqlite", 16, 16)

Here, dsn represents the file path from your configuration (./data/grok2api.db). The configureDatabase function applies common GORM settings—including connection pooling limits—and executes automatic schema migrations via db.AutoMigrate().

Application Startup

The persistence implementation is selected at runtime in backend/internal/app/application.go. The application uses a switch statement to determine which database implementation to instantiate:

switch cfg.Database.Driver {
case "sqlite":
    // use relational SQLite implementation
case "postgres":
    // use PostgreSQL implementation
}

This architecture means no source-code changes are required to swap between SQLite and PostgreSQL; only the configuration file needs modification.

SQLite-Specific Schema Handling

SQLite requires special handling for foreign key constraints. The repository manages this in backend/internal/infra/persistence/relational/schema.go, where functions like sqliteConstraintDefinition rewrite SQLite CREATE TABLE statements to ensure foreign-key constraints are enforced correctly on the SQLite engine.

This abstraction allows the same model definitions to work across both database engines without modification.

Running the Server

With the configuration in place, install dependencies and start the API server:


# Install dependencies (first time only)

go mod download

# Run the API server

go run ./backend/cmd/grok2api

On first startup, the application automatically creates the SQLite database file at the specified path and applies all schema migrations. If you need to reset the database during development, simply delete the file and restart:


# Remove existing database

rm -f ./data/grok2api.db

# Restart to recreate with fresh schema

go run ./backend/cmd/grok2api

The server entry point is located at backend/cmd/grok2api/main.go, which initializes the application context and starts the HTTP server.

Summary

  • Configuration-driven: Set database.driver: sqlite in config.yaml to switch from PostgreSQL to SQLite without code changes.
  • Pure-Go implementation: Uses glebarez/sqlite driver via backend/internal/infra/persistence/relational/database.go to avoid CGO dependencies.
  • Automatic migrations: The configureDatabase function in database.go handles schema creation and updates automatically on startup.
  • Runtime selection: backend/internal/app/application.go selects the appropriate persistence layer based on the configured driver.
  • File-based storage: SQLite stores data in a single file (e.g., ./data/grok2api.db) that is created automatically on first run.

Frequently Asked Questions

Does Grok2API require PostgreSQL for local development?

No. Grok2API supports SQLite for local development through a configuration-only change. According to the source code in backend/internal/app/application.go, the application supports both sqlite and postgres drivers, allowing you to run the entire stack locally using a file-based SQLite database without Docker or external services.

What Go SQLite driver does Grok2API use?

Grok2API uses the glebarez/sqlite driver, a pure-Go implementation of SQLite. As seen in backend/internal/infra/persistence/relational/database.go, the application imports github.com/glebarez/sqlite and opens connections via gorm.Open(glebarezsqlite.Open(dsn), gormConfig()). This eliminates the need for CGO and system-level SQLite libraries.

How does Grok2API handle database schema migrations with SQLite?

Schema migrations run automatically via GORM's AutoMigrate function. In backend/internal/infra/persistence/relational/database.go, the configureDatabase function applies common settings and executes migrations after establishing the connection. For SQLite-specific constraints, backend/internal/infra/persistence/relational/schema.go contains helper functions like sqliteConstraintDefinition that ensure foreign keys are properly enforced.

Can I switch from SQLite to PostgreSQL without changing the code?

Yes. The application uses a switch statement in backend/internal/app/application.go to select the persistence implementation based solely on the database.driver configuration value. Changing from sqlite to postgres in config.yaml is sufficient to migrate to a production database; no source code modifications are required.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →