🔄 Easy Switching
Switch databases with npm run db:switch:turso or npm run db:switch:supabase - automatic
backups included.
The astro-basics project features a sophisticated database abstraction layer that enables seamless switching between database providers without code changes or complex configuration. Switch between Supabase (PostgreSQL) and Turso (LibSQL) with a single command while maintaining full backward compatibility.
The database switching system provides:
🔄 Easy Switching
Switch databases with npm run db:switch:turso or npm run db:switch:supabase - automatic
backups included.
🛡️ Safe Operations
Built-in backup/restore system prevents configuration loss. Roll back anytime with npm run db:restore.
🎯 Auto-Detection
Smart provider detection automatically uses the best available database based on your configuration.
🧙♂️ Setup Wizard
Interactive wizard guides you through database setup with step-by-step instructions.
npm run db:statusThis shows your current database configuration, active provider, and available options.
npm run db:switch:tursonpm run db:switch:supabaseEach switch automatically:
If you’re setting up databases for the first time:
npm run db:wizardThe interactive wizard will:
.env fileThe system uses a unified interface that abstracts database-specific implementations:
// All code uses the same interface regardless of providerimport { getDatabase } from '#libs/database'
const db = getDatabase()const messages = await db.getMessages({ limit: 10 })Key Components:
src/libs/database.ts - Main abstraction layer with provider auto-detectionsrc/libs/database-types.ts - Unified TypeScript interfacessrc/libs/turso.ts - Turso (LibSQL) implementationsrc/libs/supabase.ts - Supabase (PostgreSQL) implementationThe system automatically selects databases using this priority:
DATABASE_PROVIDER=turso|supabase in .env# Supabase ConfigurationSUPABASE_URL=https://your-project-id.supabase.coSUPABASE_ANON_KEY=eyJ... # For client operationsSUPABASE_SERVICE_ROLE_KEY=eyJ... # For server operations (required)
# Optional: Explicit provider selectionDATABASE_PROVIDER=supabase# Turso ConfigurationTURSO_DATABASE_URL=libsql://your-database-name.turso.ioTURSO_AUTH_TOKEN=eyJ...
# Optional: Explicit provider selectionDATABASE_PROVIDER=turso# Configure both providers# SupabaseSUPABASE_URL=https://your-project-id.supabase.coSUPABASE_SERVICE_ROLE_KEY=eyJ...
# TursoTURSO_DATABASE_URL=libsql://your-database-name.turso.ioTURSO_AUTH_TOKEN=eyJ...
# Choose which one to use (or omit for auto-detection)DATABASE_PROVIDER=supabase# Core Commandsnpm run db:status # Show current configuration and statusnpm run db:wizard # Interactive setup for new usersnpm run db:manage # Advanced database management CLI
# Database Switching (with automatic backups)npm run db:switch:turso # Switch to Turso databasenpm run db:switch:supabase # Switch to Supabase database
# Backup Operationsnpm run db:backup # Create configuration backup onlynpm run db:restore # Restore from previous backup
# Validation & Healthnpm run db:schema # Validate database schema compatibilityThe npm run db:manage command provides additional operations:
# Test database connectionsnpm run db:manage test
# Run comprehensive health checksnpm run db:manage health
# List all tables in current databasenpm run db:manage tables
# Interactive switching with promptsnpm run db:manage switchBest for:
Configuration:
SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEYBest for:
Configuration:
TURSO_DATABASE_URL and TURSO_AUTH_TOKENPerfect for teams working with different database preferences:
# Each developer chooses their preferred databasenpm run db:wizard
# Select Turso for fast local development# or Supabase for advanced features# Test with Tursonpm run db:switch:tursonpm run dev# Run your tests...
# Switch and test with Supabasenpm run db:switch:supabasenpm run dev# Run your tests...
# Restore original setupnpm run db:restoreFor production environments, set explicit provider:
# Production .envDATABASE_PROVIDER=supabase # or turso# ... other production configsThis prevents auto-detection issues and ensures consistent behavior.
Every switching operation automatically:
.env.backupIf something goes wrong during switching:
# Automatic rollbacknpm run db:restore
# Manual rollback if neededcp .env.backup .envnpm run db:status # Verify restorationPreview changes without applying them:
# See what would happen without making changesnode scripts/switch-database.js --to turso --dry-runFor quick issues, try these common solutions:
🔧 Configuration Issues
“Database not configured” error: bash npm run db:status # Check what's missing npm run db:wizard # Run setup wizard
🔗 Connection Problems
Connection failures during switching: bash npm run db:manage test # Test connections npm run db:manage health # Run diagnostics
🎯 Provider Detection
Wrong provider selected: bash # Set explicit provider in .env echo "DATABASE_PROVIDER=turso" >> .env
🚨 Emergency Recovery
Something went wrong: bash npm run db:restore # Rollback to previous config
For detailed problem diagnosis and resolution, see our Complete Database Troubleshooting Guide:
All existing API endpoints automatically work with both databases:
import { getDatabase } from '#libs/database'
export const GET: APIRoute = async () => { const db = getDatabase() // Automatically uses active provider const data = await db.getMessages({ limit: 10 })
return new Response( JSON.stringify({ success: true, provider: db.getProviderName(), // Shows which DB is active data, }) )}Dashboard components automatically adapt to the active provider:
---import { getDatabase } from '#libs/database'import type { Message } from '#libs/database-types'
let messages: Message[] = []try { const db = getDatabase() messages = await db.getMessages({ archived: false, limit: 50 })} catch (error) { console.error('Database error:', error)}---
<div> { messages.map(message => ( <div key={message.id}> <h3>{message.name}</h3> <p>{message.message}</p> </div> )) }</div>turso for fast local development - Lower latency for frequent operationssupabase for testing advanced features - Real-time, RLS, advanced queriesnpm run db:status when joining projects - Understand current configurationDATABASE_PROVIDER explicitly - Prevent auto-detection issuesnpm run db:manage health - Regular health checksnpm run db:wizard - Consistent team onboardingThe abstraction layer is designed for minimal overhead:
.env.backup files excluded from git automaticallyIf you have an existing project using only Turso or Supabase:
getDatabase() instead of direct clientsThe system is designed to be 100% backward compatible - existing code continues working without changes.
Validate schema compatibility between providers:
npm run db:schema # Check current schemanpm run db:manage tables # List available tablesBoth providers should have compatible table structures for seamless switching.
Unlike traditional database switching that requires server restarts, this system supports real-time switching:
// Database provider changes automatically without restartconst db = getDatabase() // Always returns currently configured providerThe system provides context-aware error messages:
try { const db = getDatabase() await db.insertMessage(data)} catch (error) { // Error includes provider information for better debugging console.error(`Database operation failed (${db.getProviderName()}):`, error)}Built-in schema validation ensures compatibility:
# Validate schema before switchingnpm run db:schema
# Reports:# - Missing tables# - Column mismatches# - Type incompatibilities# - Required migrationsThe database abstraction system is designed to support:
If you encounter issues with the database switching system:
npm run db:status for current configurationnpm run db:manage test for connectivity issuesnpm run db:manage health for comprehensive diagnosticsnpm run db:wizard to start freshFor detailed troubleshooting, see the comprehensive troubleshooting guide in the project documentation.
The database switching system transforms database management from a complex, error-prone process into a simple, safe operation that any team member can perform confidently. Whether you’re a solo developer or part of a large team, the system adapts to your workflow while maintaining the flexibility to switch providers as your needs evolve.