libsql-orm
A powerful, async-first ORM for libsql with first-class support for Cloudflare Workers and WebAssembly environments.
✨ Features
- 🚀 Cloudflare Workers Ready - Built specifically for edge computing environments
- 🔄 Async/Await Support - Fully async API with excellent performance
- 🎯 Type-Safe - Leverages Rust's type system for compile-time safety
- 📊 Rich Query Builder - Fluent API for complex queries
- 🔍 Advanced Filtering - Search, pagination, sorting, and aggregations
- 🛠️ Migration System - Database schema management and versioning
- 🎨 Derive Macros - Automatic model generation with
#[derive(Model)]
- 📦 Bulk Operations - Efficient batch inserts, updates, and deletes
- 🌐 WASM Compatible - Optimized for WebAssembly targets
- 🔧 Custom Table Names -
#[table_name("custom")]
attribute support - ✅ Boolean Type Safety - Automatic SQLite integer ↔ Rust boolean conversion
- 🏷️ Column Attributes -
#[orm_column(...)]
for column customization - 🔄 Upsert Operations - Smart create_or_update and upsert methods
- 📝 Built-in Logging - Comprehensive logging for debugging and monitoring
🚀 Quick Start
Add this to your Cargo.toml
:
[]
= "0.1.0"
= { = "1.0", = ["derive"] }
= { = "0.4", = ["serde"] }
Basic Usage
use ;
use ;
use ;
// Custom table name (optional)
// In your async function
async
Cloudflare Workers Integration
use *;
use ;
// Custom table name
async
📚 Advanced Features
Custom Table Names
Use the #[table_name("custom_name")]
attribute to specify custom table names:
// Custom table name
// Default table name would be "user" (struct name lowercase)
// With attribute, table name is "user_accounts"
assert_eq!;
Benefits:
- 🏷️ Legacy Integration - Map to existing database tables
- 🎯 Naming Control - Override default naming conventions
- 📁 Multi-tenant - Use prefixes like
tenant_users
- 🔄 Migration Friendly - Rename tables without changing structs
Boolean Type Safety
libsql-orm automatically handles boolean conversion between SQLite and Rust:
// All boolean operations work seamlessly
let user = find_where.await?;
// JSON serialization works correctly
let json = to_string?; // ✅ Booleans as true/false
let deserialized: User = from_str?; // ✅ No errors
Key Features:
- ✅ Automatic Detection - Boolean fields identified at compile time
- ✅ Zero Configuration - Works with any boolean field name
- ✅ Type Safety - No runtime errors or invalid conversions
- ✅ Performance - Conversion logic generated at compile time
- ✅ JSON Compatible - Seamless serialization/deserialization
Column Attributes
Customize column properties with #[orm_column(...)]
:
Query Builder
use ;
// Complex query with filtering and pagination
let query = new
.select
.r#where
.order_by
.limit
.offset;
let = query.build?;
Pagination
use ;
let pagination = new; // page 1, 10 items per page
let result: = find_paginated.await?;
println!;
println!;
for user in result.data
Bulk Operations
// Bulk insert
let users = vec!;
let saved_users = bulk_create.await?;
// Bulk delete
let ids_to_delete = vec!;
let deleted_count = bulk_delete.await?;
Aggregations
use Aggregate;
// Count users
let total_users = count.await?;
// Average age
let avg_age = aggregate.await?;
// Count with filter
let active_users_count = count_where.await?;
Search
use SearchFilter;
let search = new;
let results = search.await?;
Upsert Operations
libsql-orm provides intelligent create-or-update operations:
use ;
// Create or update based on primary key
let mut user = User ;
// Automatically decides whether to create or update
let saved_user = user.create_or_update.await?;
// Upsert based on unique constraints (e.g., email)
let user = User ;
// Will update existing record with this email, or create new if not found
let saved_user = user.upsert.await?;
// Multiple unique constraints
let saved_user = user.upsert.await?;
Use Cases:
- ✅ Data Synchronization - Import external data without duplicates
- ✅ User Registration - Update existing accounts or create new ones
- ✅ Configuration Management - Maintain settings without conflicts
- ✅ API Endpoints - Handle PUT requests efficiently
Built-in Logging
libsql-orm includes comprehensive logging for debugging and monitoring:
use ;
// All operations are automatically logged
let user = new;
// Logs: [INFO] users: Creating record in table: users
// Logs: [DEBUG] users: SQL: INSERT INTO users (name, email, is_active) VALUES (?, ?, ?)
// Logs: [INFO] users: Successfully created record with ID: 123
let saved_user = user.create.await?;
// Logs: [DEBUG] users: Finding record by ID: 123
// Logs: [INFO] users: Found record with ID: 123
let found_user = find_by_id.await?;
// Logs: [INFO] users: Updating existing record with ID: 123
// Logs: [INFO] users: Updating record with ID: 123
// Logs: [DEBUG] users: SQL: UPDATE users SET name = ?, email = ? WHERE id = ?
// Logs: [INFO] users: Successfully updated record with ID: 123
let updated_user = found_user.unwrap.create_or_update.await?;
Logging Features:
- 🎯 Cross-Platform - Uses browser console in WASM, standard logging elsewhere
- 📊 Multiple Levels - INFO, DEBUG, WARN, ERROR levels
- 🏷️ Table Context - Automatic table name prefixing for clarity
- 🔍 SQL Debugging - View actual SQL queries being executed
- ⚡ Performance Friendly - Minimal overhead in production
Cloudflare Workers Logging:
// In browser/worker environment, logs appear in console
// [INFO] users: Creating record in table: users
// [DEBUG] users: SQL: INSERT INTO users (...) VALUES (...)
// [WARN] users: Record with ID 999 not found, creating new record
Native Application Logging:
// Configure logging in your application
use LevelFilter;
use env_logger;
from_default_env
.filter_level
.init;
// Now all ORM operations will use standard Rust logging
🔧 Migrations
libsql-orm includes a powerful migration system:
use ;
// Auto-generate migration from model
let migration = generate_migration!;
// Or create manually
let migration = new
.up
.down
.build;
// Execute migration
let manager = new;
manager.execute_migration.await?;
🏗️ Architecture
WASM Compatibility
libsql-orm is built from the ground up for WebAssembly environments:
- Uses
libsql
WASM bindings for database connectivity - Optimized async runtime for edge computing
- Minimal binary size with selective feature compilation
- Compatible with Cloudflare Workers, Deno Deploy, and other edge platforms
Performance
- Zero-copy deserialization where possible
- Connection pooling for optimal database usage
- Lazy loading of related data
- Efficient batch operations for bulk data handling
📖 Examples
Complete CRUD Example
use ;
use ;
use ;
async
🔗 Ecosystem
libsql-orm works great with:
- libsql - The database engine
- Turso - Managed libsql hosting
- Cloudflare Workers - Edge computing platform
- worker-rs - Cloudflare Workers Rust SDK
🔧 Troubleshooting
Boolean Serialization Issues
If you encounter errors like "invalid type: integer '1', expected a boolean"
, you have two solutions:
Option 1: Automatic Conversion (Recommended)
The derive macro handles this automatically in most cases:
// ✅ This works automatically with the derive macro
Option 2: Manual Deserializer (For Edge Cases)
If automatic conversion doesn't work, use the custom deserializer:
use deserialize_bool;
The deserialize_bool
function handles:
- ✅ Integers:
0
→false
,1
→true
- ✅ Booleans: Pass through unchanged
- ✅ Strings:
"true"
,"1"
,"yes"
→true
;"false"
,"0"
,"no"
→false
Table Name Conflicts
Use the #[table_name("custom")]
attribute to resolve naming conflicts:
// Avoid conflicts with system tables
🤝 Contributing
Contributions are welcome! Please read our Contributing Guide for details.
Development Setup
Running Tests
# Unit tests
# Integration tests with real database
# WASM tests
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- libsql team for the excellent database engine
- Cloudflare for the Workers platform
- Rust community for the amazing ecosystem
📊 Status
- ✅ Stable API - Ready for production use
- ✅ Well Tested - Comprehensive test suite
- ✅ Documented - Complete API documentation
- ✅ WASM Ready - Optimized for edge computing
- 🔄 Active Development - Regular updates and improvements
Need help?
- 📚 Documentation
- 💬 Discussions
- 🐛 Issues