SuperAPI AI Directory

turso-best-practices

Coding & development

View repository

Updated 10-15 21:49

About this skill

Turso & libSQL Best Practices

Reference Files

File When to read
references/advanced-features.md Working with embedded replicas, vector search/AI embeddings, Drizzle ORM, database branching, encryption at rest, or SQLite extensions

Overview

Turso is a fully managed SQLite-compatible database platform built on libSQL, a fork of SQLite. It provides edge distribution, embedded replicas, native vector search, branching, and point-in-time recovery. Core principle: SQLite simplicity with cloud-scale distribution.

When to Use

  • Building applications needing SQLite with cloud features
  • Implementing embedded replicas for offline-first apps
  • Adding vector search/AI embeddings to applications
  • Setting up local development with Turso
  • Managing database migrations and branching

Quick Reference

Task Command/Pattern
Install CLI (macOS) brew install tursodatabase/tap/turso
Install CLI (Linux) curl -sSfL https://get.tur.so/install.sh | bash
Login turso auth login
Create database turso db create my-db
Connect to shell turso db shell my-db
Get credentials turso db show my-db --url and turso db tokens create my-db
Local dev server turso dev
Local with file turso dev --db-file local.db

Installation & Setup

CLI Installation

# macOS
brew install tursodatabase/tap/turso

# Linux / Windows (WSL)
curl -sSfL https://get.tur.so/install.sh | bash

Authentication

turso auth signup     # Sign up (opens browser)
turso auth login      # Login (opens browser)
turso auth login --headless  # Headless mode (WSL/CI)

Create Your First Database

turso db create my-db          # Auto-detects closest region
turso db show my-db            # Show database info
turso db show my-db --url      # Get connection URL
turso db tokens create my-db   # Create auth token
turso db shell my-db           # Connect to shell

SDK Usage (TypeScript/JavaScript)

Installation

npm install @libsql/client

Basic Connection

import { createClient } from '@libsql/client'

const client = createClient({
  url: process.env.TURSO_DATABASE_URL!,
  authToken: process.env.TURSO_AUTH_TOKEN,
})

Execute Queries

// Simple query
const result = await client.execute('SELECT * FROM users')

// Positional placeholders
const result = await client.execute({
  sql: 'SELECT * FROM users WHERE id = ?',
  args: [1],
})

// Named placeholders (:, @, or $)
const result = await client.execute({
  sql: 'INSERT INTO users (name, email) VALUES (:name, :email)',
  args: { name: 'Alice', email: 'alice@example.com' },
})

Response Structure

interface ResultSet {
  rows: Array<Row>         // Row data (empty for writes)
  columns: Array<string>   // Column names
  rowsAffected: number     // Affected rows (writes)
  lastInsertRowid?: bigint // Last inserted row ID
}

Batch Transactions

const results = await client.batch(
  [
    { sql: 'INSERT INTO users (name) VALUES (?)', args: ['Alice'] },
    { sql: 'INSERT INTO users (name) VALUES (?)', args: ['Bob'] },
  ],
  'write' // Transaction mode: "write" | "read" | "deferred"
)

Interactive Transactions

const transaction = await client.transaction('write')

try {
  const balance = await transaction.execute({
    sql: 'SELECT balance FROM accounts WHERE id = ?',
    args: [userId],
  })

  if (balance.rows[0].balance >= amount) {
    await transaction.execute({
      sql: 'UPDATE accounts SET balance = balance - ? WHERE id = ?',
      args: [amount, userId],
    })
    await transaction.commit()
  } else {
    await transaction.rollback()
  }
} catch (e) {
  await transaction.rollback()
  throw e
}

Transaction Modes

Mode SQLite Command Description
write BEGIN IMMEDIATE Read/write, serialized on primary
read BEGIN TRANSACTION READONLY Read-only, can run on replicas in parallel
deferred BEGIN DEFERRED Starts as read, upgrades to write on first write

Local Development

Option 1: SQLite File (Simplest)

const client = createClient({ url: 'file:local.db' })

Option 2: Turso Dev Server (Full Features)

turso dev                    # Start local libSQL server
turso dev --db-file local.db # With persistent file
const client = createClient({ url: 'http://127.0.0.1:8080' })

Environment Variables Pattern

# Production
TURSO_DATABASE_URL=libsql://my-db-org.turso.io
TURSO_AUTH_TOKEN=eyJ...

# Development
TURSO_DATABASE_URL=file:local.db
# No auth token needed

Common Mistakes

Mistake Fix
Using @libsql/client/web with file URLs Use @libsql/client for local files
Long-running write transactions Keep writes short, they block other writes
Opening local file during sync Wait for sync to complete
Forgetting to sync embedded replicas Call sync() or use syncInterval
Hardcoding credentials Use environment variables
Not using transactions for related writes Use batch() or transaction()

Performance Tips

  • Use batch() for multiple related operations
  • Use read transactions for read-only queries (parallel on replicas)
  • Set appropriate syncInterval for embedded replicas
  • Use vector indexes for tables with >1000 rows
  • Use positional placeholders for frequently executed queries