Overview
Featul uses Drizzle ORM with PostgreSQL (via Neon serverless) for data persistence. Drizzle provides type-safe database queries with excellent TypeScript inference.Database Provider
Neon Serverless
Featul uses Neon for PostgreSQL hosting:- Serverless: Auto-scaling with no connection limits
- Branching: Database branches for development
- Edge: Low-latency connections from serverless functions
- Cost-effective: Pay for storage, not compute time
Connection Setup
Database client inpackages/db/index.ts:1:
neon-http) is optimized for serverless environments.
Schema Organization
File Structure
Schemas are organized by domain inpackages/db/schema/:
Schema Exports
All schemas are re-exported frompackages/db/schema/index.ts:
Schema Examples
Workspace Schema
Frompackages/db/schema/workspace.ts:5:
Workspace Members
Frompackages/db/schema/workspace.ts:60:
Custom Domain Verification
Frompackages/db/schema/workspace.ts:30:
Querying the Database
Basic Queries
Joins
Insert
Update
Delete
Aggregations
Frompackages/api/src/router/workspace.ts:138:
Migrations
Configuration
Drizzle Kit config inpackages/db/drizzle.config.ts:
Generate Migration
After modifying schema files:packages/db/drizzle/.
Push Schema (Development)
For rapid development, push schema directly:Run Migrations (Production)
Apply pending migrations:Drizzle Studio
Open the visual database browser:https://local.drizzle.studio
Type Safety
Inferred Types
Drizzle automatically infers types from schema:Custom Types with JSON
Best Practices
ID Generation
Use CUID2 for unique IDs:Timestamps
Always include timestamps:Foreign Keys
Use cascading deletes for parent-child relationships:Indexes
Add indexes for frequently queried columns:Unique Constraints
Advanced Patterns
Conditional Queries
Transactions
Prepared Statements
Performance Tips
Select Only Needed Columns
Use Indexes
Add indexes for:- Foreign keys (workspaceId, userId, etc.)
- Frequently filtered columns (status, createdAt)
- Unique constraints (email, slug)
Batch Operations
Limit Results
Troubleshooting
Type Errors
If types are not updating:- Ensure schema files are saved
- Restart TypeScript server
- Check imports are from
@featul/db
Migration Conflicts
If migrations fail:- Check database state with
bun run db:studio - Review migration SQL in
drizzle/directory - Manually fix database if needed
- Regenerate migrations from clean state
Connection Issues
VerifyDATABASE_URL is set:
.env.local for local development.