# How to Set Up Grok2API for Local Development with SQLite

> Easily set up Grok2API for local development with SQLite. Configure your API to use SQLite with a simple change in config yaml for a dependency-free local environment.

- Repository: [Chenyme/grok2api](https://github.com/chenyme/grok2api)
- Tags: how-to-guide
- Published: 2026-07-16

---

**Grok2API supports SQLite via a thin GORM abstraction layer, requiring only a configuration change to `driver: sqlite` in [`config.yaml`](https://github.com/chenyme/grok2api/blob/main/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`](https://github.com/chenyme/grok2api/blob/main/docker-compose.yml) for testing PostgreSQL production configurations.

## Configuration

The database driver is controlled through the [`config.yaml`](https://github.com/chenyme/grok2api/blob/main/config.yaml) file. Copy the provided example configuration and modify the `database` section:

```bash
cp config.example.yaml config.yaml

```

Edit [`config.yaml`](https://github.com/chenyme/grok2api/blob/main/config.yaml) to specify SQLite as the driver:

```yaml
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`](https://github.com/chenyme/grok2api/blob/main/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`](https://github.com/chenyme/grok2api/blob/main/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:

```go
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`](https://github.com/chenyme/grok2api/blob/main/backend/internal/app/application.go). The application uses a switch statement to determine which database implementation to instantiate:

```go
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`](https://github.com/chenyme/grok2api/blob/main/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:

```bash

# 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:

```bash

# 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`](https://github.com/chenyme/grok2api/blob/main/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`](https://github.com/chenyme/grok2api/blob/main/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`](https://github.com/chenyme/grok2api/blob/main/backend/internal/infra/persistence/relational/database.go) to avoid CGO dependencies.
- **Automatic migrations**: The `configureDatabase` function in [`database.go`](https://github.com/chenyme/grok2api/blob/main/database.go) handles schema creation and updates automatically on startup.
- **Runtime selection**: [`backend/internal/app/application.go`](https://github.com/chenyme/grok2api/blob/main/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`](https://github.com/chenyme/grok2api/blob/main/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`](https://github.com/chenyme/grok2api/blob/main/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`](https://github.com/chenyme/grok2api/blob/main/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`](https://github.com/chenyme/grok2api/blob/main/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`](https://github.com/chenyme/grok2api/blob/main/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`](https://github.com/chenyme/grok2api/blob/main/config.yaml) is sufficient to migrate to a production database; no source code modifications are required.