---
title: "SQLite"
description: "Use SQLite as the MainSDK local data driver - offline development with no database server, main.yaml overlays, testing, and why production refuses it."
section: "integrations"
canonical: "https://mainsdk.dev/docs/integrations/sqlite"
updated: "2026-10-28"
---

# SQLite

> Use SQLite as the MainSDK local data driver - offline development with no database server, main.yaml overlays, testing, and why production refuses it.

Canonical: https://mainsdk.dev/docs/integrations/sqlite · Updated: 2026-10-28

SQLite is the local driver behind [`db`](https://mainsdk.dev/docs/interfaces/db). It keeps your records in a file on your machine, so `mainsdk dev` runs offline with no database server, cloud account or connection string. Your code calls the same `db.<model>.for(user)` methods it calls in production. Pick it for local development and quick prototypes; production uses Postgres, Neon or Supabase, and `mainsdk check` enforces that.

## Interfaces it serves

### Data and records (`db`)

- Status: Building for 0.3 · ships as a stable API
- Driver: `sqlite` (SQLite (local only))
- Docs: https://mainsdk.dev/docs/interfaces/db.md

```yaml
db:
  driver: sqlite
```

Swap to another provider: `postgres`, `neon`, `supabase`.

## Before you start

Nothing to set up. SQLite is an embedded database that runs inside your app's process, so there is no server, account or key.

1. **Install MainSDK** and run `mainsdk dev`. Every interface ships a local driver, and SQLite is the one for `db`.
2. **Pick a production driver early,** such as [Postgres](https://mainsdk.dev/docs/integrations/postgres), so your production overlay is ready before your first deploy.

## Configure

Keep SQLite in your development overlay and a real driver in production.

```yaml title="main.env.dev.yaml"
db:
  driver: sqlite
```

```yaml title="main.env.prod.yaml"
db:
  driver: postgres
  regions: { us: secret:DB_US, eu: secret:DB_EU, in: secret:DB_IN }   # suggested names
```

Where the SQLite file lives, and how the local driver handles the `us`, `eu` and `in` regions, are not defined yet [TBD]. Field labels under `db.fields` apply as they do on any driver.

## Use it

```ts title="app/api/orders/route.ts"
import { auth, db } from "mainsdk";

export async function GET(req: Request) {
  const session = await auth.require(req);
  const orders = await db.orders.for(session.user).list({ limit: 20 });
  return Response.json(orders);
}
```

The same code runs unchanged when production points `db` at Postgres.

## Local development and testing

- **`mainsdk dev`:** runs `db` on SQLite with no provider key or network.
- **Tests:** `createTestApp()` from `@mainsdk/testing` runs `db` on its in-memory fake, and `chaos.on("db", { outage: true })` simulates the store going down.
- **Before you ship:** run `npx mainsdk check --env prod` locally or in CI to confirm production no longer resolves to SQLite.

## What MainSDK adds on top

- No query without an owner scope, on SQLite as on every driver.
- Personal fields carry a label; a field labelled `pan` is refused.
- A repeated idempotency key on `create` or `update` never writes twice.
- Production can't run on it: `mainsdk check` fails with `MAIN-DATA-0030`.

See [Data and records](https://mainsdk.dev/docs/interfaces/db) for the full contract.

## Limits and notes

- Local only. Setting `db.driver: sqlite` for production fails `mainsdk check` with `MAIN-DATA-0030`; set `db.driver` to `postgres`, `neon` or `supabase` for prod.
- The SQLite driver comes with the db spec (phase 1).
- SQLite is not a regional store, so it does not prove your residency setup; test region routing against your real driver.

## Swap to or from it

```yaml title="main.env.prod.yaml"
db:
  driver: postgres   # was sqlite
```

> **Warning:** Local rows don't move to production on their own. Seed or migrate production data through your usual migrations; MainSDK runs a move between stores as a guided migration job with a rollback, not a silent switch.

## FAQ

**Can I use SQLite in production for a small app?** No. The check refuses it with `MAIN-DATA-0030`, so every production app gets regional stores, backups and drills from a real provider.

**Do my Prisma or Drizzle migrations work with it?** The db spec pairs the SQLite local driver with Prisma and Drizzle adapters; how migrations run against the local file is [TBD].

## Next

- [Data and records](https://mainsdk.dev/docs/interfaces/db)
- [Postgres](https://mainsdk.dev/docs/integrations/postgres) and [Neon](https://mainsdk.dev/docs/integrations/neon)
- [Swap a driver](https://mainsdk.dev/docs/guides/swap-a-driver)
