Buildspace
Database

Schema & Queries

Define your database schema and run queries with Drizzle ORM.

You own your database schema entirely. Buildspace provisions the database — you define the tables, run migrations, and write queries.

Define a schema

Create a schema file (e.g. schema.ts):

import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";

export const todos = sqliteTable("todos", {
  id: integer("id").primaryKey({ autoIncrement: true }),
  userId: text("user_id").notNull(),
  text: text("text").notNull(),
  completed: integer("completed").notNull().default(0),
  createdAt: text("created_at")
    .notNull()
    .$defaultFn(() => new Date().toISOString()),
});

Then pass the schema to Drizzle when creating the client:

import { createClient } from "@libsql/client";
import { drizzle } from "drizzle-orm/libsql";
import * as schema from "./schema";

const client = createClient({
  url: process.env.BUILDSPACE_DB_URL!,
  authToken: process.env.BUILDSPACE_DB_TOKEN!,
});

export const db = drizzle(client, { schema });

Run queries

With the schema-aware client you get full type safety:

import { eq } from "drizzle-orm";
import { db } from "./db";
import { todos } from "./schema";

// Insert
await db.insert(todos).values({
  userId: "user_123",
  text: "Ship the feature",
});

// Select
const userTodos = await db
  .select()
  .from(todos)
  .where(eq(todos.userId, "user_123"));

// Update
await db
  .update(todos)
  .set({ completed: 1 })
  .where(eq(todos.id, 1));

// Delete
await db.delete(todos).where(eq(todos.id, 1));

Push schema to Turso

Use drizzle-kit push to apply your schema directly to the database without generating migration files:

npx drizzle-kit push

Create a drizzle.config.ts at the root of your project:

import { defineConfig } from "drizzle-kit";

export default defineConfig({
  schema: "./schema.ts",
  dialect: "turso",
  dbCredentials: {
    url: process.env.BUILDSPACE_DB_URL!,
    authToken: process.env.BUILDSPACE_DB_TOKEN!,
  },
});

Migrations (optional)

If you prefer versioned migrations instead of push:

# Generate a migration
npx drizzle-kit generate

# Apply migrations
npx drizzle-kit migrate

Migration files are stored in a drizzle/ directory by default. Commit them to your repo for reproducible deploys.

Tips

  • SQLite-compatible — Turso databases use libSQL (a SQLite fork). Use SQLite column types (integer, text, real, blob) in your Drizzle schema.
  • One database per environment — Dev and prod schemas can drift independently. Run drizzle-kit push against each environment separately.
  • No shared schema — The platform does not inject or manage any tables in your database. It's a blank database for your app to use however you want.

On this page