JSPM

mist-orm

0.1.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • 0
  • Score
    100M100P100Q54583F
  • License Apache-2.0

Convention-based data layer for TypeScript. Auto-generate Drizzle ORM schemas from TypeScript interfaces.

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.

License: Apache-2.0

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 passingPostgreSQL and SQLite supportProduction-ready

Quick Start

Installation

npm install mist-orm drizzle-orm
# For PostgreSQL
npm install postgres
# For SQLite
npm install better-sqlite3

1. 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 dev

This 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 date

Migration workflow:

  • Modify your TypeScript interfaces
  • Run mist migrate:generate to detect changes and create SQL migrations
  • Review the generated .mist/migrations/*.sql files
  • Run mist migrate:up to 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 createdAt and updatedAt timestamps
    • Foreign key detection (userIdusers.id)
    • Unique constraints via JSDoc (/** @unique */)
  • 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 output

Example:

npx mist generate
npx mist generate --config ./custom.config.ts --verbose

mist 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 regeneration

Example:

npx mist dev

mist 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 output

Example:

npx mist migrate:generate

This command:

  1. Generates schemas from your TypeScript interfaces
  2. Compares them with the previous snapshot
  3. Detects all schema changes (added/removed tables, column changes, etc.)
  4. Generates SQL migration files via Drizzle Kit
  5. 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 output

Example:

npx mist migrate:up

Applies 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:status

Displays:

  • 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 operation

Example:

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 config

Conventions

Primary Keys

Every table automatically gets an id primary key:

  • PostgreSQL: uuid with defaultRandom()
  • SQLite: integer with auto-increment

Timestamps

Tables automatically include:

  • createdAt: timestamp - Set on record creation
  • updatedAt: 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.json

Important: 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 generate command
  • mist dev watch 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
  • userId references users.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 lint

Documentation

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

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:

  1. Check the issues or roadmap
  2. Fork the repository
  3. Create a feature branch
  4. Write tests for your changes
  5. Ensure all tests pass (npm test)
  6. 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.