Package Exports
- mist-orm
- mist-orm/package.json
Readme
mist-orm
Convention-based data layer for TypeScript. Auto-generate Drizzle ORM schemas from TypeScript interfaces.
Status: v1.0 Ready! 🎉
mist-orm has reached v1.0 with full migration support and production-ready features.
Current State
- ✅ Phase 1 Complete: Core schema generation (TypeScript → Drizzle schemas)
- ✅ Phase 2 Complete: Runtime client with type-safe CRUD operations
- ✅ Phase 3 Complete: CLI with generate and dev (watch) modes
- ✅ Phase 4 Complete: Migration system with automatic schema diff detection
123 tests passing • PostgreSQL and SQLite support • Production-ready
Quick Start
Installation
npm install mist-orm drizzle-orm
# For PostgreSQL
npm install postgres
# For SQLite
npm install better-sqlite31. Define Your Models
Create TypeScript interfaces for your domain models:
// models/user.ts
export interface User {
name: string
email: string
age?: number
}
// models/post.ts
export interface Post {
title: string
content: string
userId: string // Automatically creates foreign key to users.id
}2. Create Configuration
Create mist.config.ts in your project root:
export default {
models: './models/**/*.ts',
output: './.mist',
connection: 'postgresql://localhost/mydb', // or './data.db' for SQLite
}3. Generate Schemas
# One-time generation
npx mist generate
# Or watch mode for development
npx mist devThis generates Drizzle ORM schemas in .mist/schema/ and type definitions in .mist/types/.
4. Use the Generated Client
import { db } from './.mist/client'
// Insert
const user = await db.users.insert({
name: 'Alice',
email: 'alice@example.com',
age: 30
})
// Query
const users = await db.users.findMany({ age: 30 })
const alice = await db.users.findOne({ email: 'alice@example.com' })
// Update
await db.users.update(
{ email: 'alice@example.com' },
{ age: 31 }
)
// Delete
await db.users.delete({ email: 'alice@example.com' })5. Manage Database Migrations
When you update your TypeScript interfaces, mist-orm can automatically generate migrations:
# 1. Update your interfaces (add/remove fields, tables, etc.)
# models/user.ts
export interface User {
name: string
email: string
age?: number
bio?: string // New field added
}
# 2. Generate a migration
npx mist migrate:generate
# Output:
# ✓ Generated 1 schemas
# ✓ Migration generated
#
# Generated migration files:
# • 0001_warm_captain_britain.sql
#
# To apply the migration, run:
# mist migrate:up
# 3. Apply the migration
npx mist migrate:up
# Output:
# ✓ Configuration loaded
# ✓ Found 1 pending migration(s)
# ✓ Migrations applied successfully
# ✓ Database is up to date!
# 4. Check migration status anytime
npx mist migrate:status
# Output:
# 📊 Migration Status
#
# Total migrations: 1
# Applied: 1
# Pending: 0
# Current version: 0001_warm_captain_britain
#
# ✓ Database is up to dateMigration workflow:
- Modify your TypeScript interfaces
- Run
mist migrate:generateto detect changes and create SQL migrations - Review the generated
.mist/migrations/*.sqlfiles - Run
mist migrate:upto apply migrations to your database - Migrations are tracked automatically - only pending migrations will be applied
Features
✅ Implemented (v1.0)
- Auto-generate Drizzle schemas from TypeScript interfaces
- Convention-based patterns:
- Auto-generated
id(UUID for Postgres, integer for SQLite) - Auto-generated
createdAtandupdatedAttimestamps - Foreign key detection (
userId→users.id) - Unique constraints via JSDoc (
/** @unique */)
- Auto-generated
- PostgreSQL and SQLite support with the same code
- Type-safe CRUD operations: insert, findOne, findMany, update, delete
- CLI commands:
generate,dev(watch mode),migrate(migrations) - Migration system (Phase 4):
- Automatic schema diff detection
- SQL migration file generation via Drizzle Kit
- Migration tracking and status
- Database reset with safety confirmations
- Schema snapshot versioning
- Configuration file support (mist.config.ts)
- File watching with auto-regeneration and debouncing
🚧 Planned (Future Releases)
- Advanced queries - Comparison operators, ordering, pagination (Phase 5)
- Relationship loading - Include related records (Phase 5)
- Validation - Zod schema generation (Phase 5)
CLI Reference
mist generate
Generate Drizzle schemas from your TypeScript interfaces.
mist generate [options]
Options:
-c, --config <path> Path to config file (default: "./mist.config.ts")
-v, --verbose Verbose outputExample:
npx mist generate
npx mist generate --config ./custom.config.ts --verbosemist dev
Watch mode with automatic regeneration on file changes.
mist dev [options]
Options:
-c, --config <path> Path to config file (default: "./mist.config.ts")
-v, --verbose Verbose output
--no-clear Don't clear console on regenerationExample:
npx mist devmist migrate
Manage database migrations with automatic schema diff detection.
mist migrate:generate
Generate a new migration from schema changes.
mist migrate:generate [options]
Options:
-c, --config <path> Path to config file (default: "./mist.config.ts")
-v, --verbose Verbose outputExample:
npx mist migrate:generateThis command:
- Generates schemas from your TypeScript interfaces
- Compares them with the previous snapshot
- Detects all schema changes (added/removed tables, column changes, etc.)
- Generates SQL migration files via Drizzle Kit
- Saves a new snapshot for future comparisons
mist migrate:up
Apply pending migrations to the database.
mist migrate:up [options]
Options:
-c, --config <path> Path to config file (default: "./mist.config.ts")
-v, --verbose Verbose outputExample:
npx mist migrate:upApplies all pending migrations in order and tracks them in the database.
mist migrate:status
Show migration status and information.
mist migrate:status [options]
Options:
-c, --config <path> Path to config file (default: "./mist.config.ts")Example:
npx mist migrate:statusDisplays:
- Total migrations
- Applied migrations
- Pending migrations
- Current version
- Latest snapshot info
mist migrate:reset
Reset all migrations (destructive operation).
mist migrate:reset --force
Options:
--force Required to confirm the operationExample:
npx mist migrate:reset --force⚠️ Warning: This drops all tables and reapplies all migrations. Use with caution!
Configuration
Create mist.config.ts in your project root:
import type { MistConfig } from 'mist-orm'
const config: MistConfig = {
// Required: Glob pattern(s) for model files
models: './models/**/*.ts',
// Required: Output directory for generated files
output: './.mist',
// Required: Database connection string
// PostgreSQL: 'postgresql://user:pass@host/db'
// SQLite: './path/to/database.db'
connection: process.env.DATABASE_URL || 'postgresql://localhost/mydb',
// Optional: Convention overrides
conventions: {
timestamps: true, // Auto-add createdAt/updatedAt (default: true)
primaryKey: 'id', // Primary key field name (default: 'id')
foreignKeys: { // Custom foreign key mappings
authorId: 'users', // Map authorId → users.id
},
unique: { // Unique constraints per table
User: ['email'],
Post: ['slug'],
},
exclude: ['internal'], // Fields to exclude from schema
},
// Optional: Database-specific settings
database: {
type: 'postgres', // 'postgres' or 'sqlite' (auto-detected)
schema: 'public', // PostgreSQL schema name (default: 'public')
},
// Optional: Development mode settings
dev: {
autoMigrate: false, // Auto-push schema changes (default: false)
watch: ['./lib/**/*.ts'], // Additional paths to watch
},
}
export default configConventions
Primary Keys
Every table automatically gets an id primary key:
- PostgreSQL:
uuidwithdefaultRandom() - SQLite:
integerwith auto-increment
Timestamps
Tables automatically include:
createdAt: timestamp- Set on record creationupdatedAt: timestamp- Updated on every modification
Disable with conventions.timestamps = false.
Foreign Keys
Fields ending in Id automatically create foreign key relationships:
interface Post {
userId: string // Creates: references(() => users.id)
authorId: string // Creates: references(() => authors.id)
}Override with conventions.foreignKeys:
conventions: {
foreignKeys: {
authorId: 'users' // Maps authorId → users.id instead of authors.id
}
}Unique Constraints
Add unique constraints via JSDoc or configuration:
interface User {
/** @unique */
email: string
}Or in config:
conventions: {
unique: {
User: ['email', 'username']
}
}Type Mapping
| TypeScript Type | PostgreSQL | SQLite |
|---|---|---|
string |
text |
text |
number |
integer |
integer |
boolean |
boolean |
integer (0/1) |
Date |
timestamp |
integer (unix) |
string[] |
text[] (array) |
text (JSON) |
object |
jsonb |
text (JSON) |
Project Structure
your-project/
├── models/ # Your TypeScript interfaces
│ ├── user.ts
│ └── post.ts
├── .mist/ # Generated files (auto-generated)
│ ├── schema/ # Drizzle table definitions
│ │ ├── index.ts
│ │ ├── users.ts
│ │ └── posts.ts
│ ├── types/ # TypeScript type definitions
│ │ ├── index.ts
│ │ ├── users.ts
│ │ └── posts.ts
│ ├── migrations/ # SQL migration files
│ │ ├── meta/ # Migration metadata
│ │ └── 0000_*.sql # Migration SQL files
│ ├── snapshots/ # Schema snapshots for diff detection
│ │ ├── latest.json
│ │ └── 2025-*.json
│ ├── drizzle.config.ts # Drizzle Kit configuration
│ └── client.ts # Generated database client
├── mist.config.ts # Configuration file
└── package.jsonImportant: Add .mist/ to your .gitignore. These files are auto-generated.
Development Phases
Phase 0: Project Setup ✅
- Package initialization and configuration
- Build tooling (tsup, TypeScript)
- Testing framework (vitest)
- Linting and formatting (ESLint, Prettier)
Phase 1: Core Schema Generation ✅
- TypeScript AST parser for interfaces
- Convention detection (primary keys, timestamps, foreign keys)
- Type mapping (TypeScript → SQL)
- Drizzle schema code generation (PostgreSQL & SQLite)
- File writing system
Phase 2: Runtime Client ✅
- Database connection management
- CRUD operations (insert, findOne, findMany, update, delete)
- Generated typed client
Phase 3: CLI & Watch Mode ✅
- CLI framework with commands
-
mist generatecommand -
mist devwatch mode - Configuration file support
Phase 4: Migrations (v1.0) ✅
- Schema snapshot system
- Schema diff detection (all change types)
- Migration file generation via Drizzle Kit
- Migration runner with tracking
- Migration status command
- Database reset command
Phase 5: Advanced Features 🚧
See context-network/planning/roadmap.md for detailed roadmap.
Why mist-orm?
Most CRUD applications follow similar patterns:
- Tables have IDs and timestamps
userIdreferencesusers.id- TypeScript types map to SQL types
Stop rewriting the same schema boilerplate. Mist applies these conventions automatically while maintaining full type safety through Drizzle ORM.
Compared to Other ORMs
vs. Prisma:
- Lighter weight, uses Drizzle under the hood
- No schema file to maintain
- Convention-based vs. explicit schema
vs. Drizzle ORM alone:
- Eliminates manual schema definition
- Auto-generates type-safe client
- Convention-based patterns
vs. TypeORM:
- Simpler, convention-based approach
- Better TypeScript integration
- Smaller bundle size
Development Setup
# Clone the repository
git clone https://github.com/jwynia/mist-orm.git
cd mist-orm
# Install dependencies
npm install
# Run build
npm run build
# Run tests (123 tests)
npm test
# Type checking
npm run typecheck
# Linting
npm run lintDocumentation
Detailed planning and architecture documentation:
Philosophy
- Interfaces are the source of truth - Domain models define the database
- Conventions over configuration - Sensible defaults eliminate boilerplate
- Zero-config for common cases - Works out of the box for typical patterns
- Escape hatches available - Drop down to Drizzle for complex scenarios
- TypeScript-first - Type safety throughout
Built On
- TypeScript - Language and type system
- Drizzle ORM - Underlying ORM layer
- Commander.js - CLI framework
- Chokidar - File watching
- tsup - Build tool
- Vitest - Testing framework
Examples
See the examples directory for:
- Basic usage example
- PostgreSQL setup
- SQLite setup
Limitations (Current v1.0)
- Basic query operations - Advanced filtering coming in Phase 5
- No relationship loading - Manual joins required (Phase 5)
- Simple validation only - Zod integration planned for Phase 5
- No migration rollback - Drizzle ORM doesn't support down migrations yet
License
Apache-2.0 © 2025 mist-orm contributors
See LICENSE file for details.
Contributing
We welcome contributions! The project is in active development.
To contribute:
- Check the issues or roadmap
- Fork the repository
- Create a feature branch
- Write tests for your changes
- Ensure all tests pass (
npm test) - Submit a pull request
For major changes, please open an issue first to discuss your proposal.
Changelog
See CHANGELOG.md for version history (coming soon).
Note: This README reflects the current MVP state of the project. Features marked as complete are fully functional and tested.