Skip to content

Dialect Independence: Split Database Dialects into Separate Packages #89

@IzumiSy

Description

@IzumiSy

🎯 Overview

Refactor the current monolithic CLI package to support database dialects as independent packages, improving extensibility, maintainability, and bundle size optimization.

📊 Current State

Monolithic Structure Issues

packages/cli/src/
├── introspection/
│   ├── postgres.ts      # PostgreSQL + CockroachDB introspection
│   ├── duckdb.ts        # DuckDB introspection  
│   └── introspector.ts  # Dialect selection logic
├── dialects/
│   └── cockroachdb.ts   # CockroachDB Kysely dialect
├── dev/
│   └── container.ts     # Container management for all dialects
└── client.ts            # All dialect imports bundled

Problems:

  • All dialect dependencies bundled regardless of usage
  • Adding new dialects requires core package changes
  • Difficult to maintain dialect-specific features independently
  • Large bundle size for users who only need specific dialects

🏗️ Proposed Architecture

New Package Structure

kyrage/
├── packages/
│   ├── core/                     # 🆕 Common interfaces & types
│   ├── cli/                      # 📦 Refactored CLI with dynamic loading
│   ├── dialect-postgres/         # 🆕 PostgreSQL dialect package
│   ├── dialect-cockroachdb/      # 🆕 CockroachDB dialect package
│   ├── dialect-duckdb/           # 🆕 DuckDB dialect package
│   ├── dialect-sqlite/           # 🆕 SQLite dialect package (future)
│   └── kyrage/                   # 🆕 All-in-one meta package
└── examples/
    └── basic/
        └── kyrage.config.ts      # ✅ No changes required

Package Responsibilities

@kyrage/core

  • Common TypeScript interfaces and types
  • Base error classes
  • Configuration schemas
  • No database-specific dependencies

@kyrage/cli

  • Command-line interface implementation
  • Dynamic dialect loading system
  • Migration management logic
  • Depends on @kyrage/core only

@kyrage/dialect-* packages

  • Database-specific introspection logic
  • Kysely dialect implementations
  • Dev database management (server-based dialects only)
  • Type name conversion utilities

@kyrage/kyrage (Meta package)

  • Re-exports all official dialect packages
  • Provides seamless upgrade path for existing users
  • Maintains current DX for new users who want "everything"

🔧 User Interface Design

Installation Options

Option 1: All-in-one (Recommended for new users)

npm install @kyrage/kyrage

Option 2: Minimal installation (Advanced users)

npm install @kyrage/cli @kyrage/dialect-postgres

Configuration File (No Breaking Changes)

// kyrage.config.ts - Works exactly the same
export default defineConfig({
  database: {
    dialect: "postgres", // Auto-loads @kyrage/dialect-postgres
    connectionString: "...",
  },
  dev: {
    container: {
      image: "postgres:16",
    },
  },
  tables: [...]
})

CLI Commands (No Breaking Changes)

# All existing commands work identically
kyrage generate
kyrage apply
kyrage generate --dev
kyrage dev start

🚫 Dev Database Support Strategy

Supported Dialects (Server-based)

  • PostgreSQL: Container-based dev database
  • CockroachDB: Container-based dev database
  • MySQL: Container-based dev database (future)

Unsupported Dialects (File-based)

  • DuckDB: Runtime error with guidance
  • SQLite: Runtime error with guidance

Error Handling Example

$ kyrage generate --dev  # with DuckDB dialect
❌ Error: Dev database is not supported for dialect "duckdb".

💡 Recommendation: Use environment-specific configuration instead:

// kyrage.config.ts
import { defineConfig } from "@izumisy/kyrage";

export default defineConfig({
  $development: {
    database: {
      dialect: "duckdb",
      connectionString: "./dev.duckdb"
    }
  },
  $production: {
    database: {
      dialect: "duckdb", 
      connectionString: "./prod.duckdb"
    }
  },
  tables: [
    /* ... */
  ]
});

Then run: NODE_ENV=development kyrage generate

📦 Package Dependencies

Core Package

{
  "name": "@kyrage/core",
  "dependencies": {
    "kysely": "^0.27.0",
    "zod": "^3.22.0"
  }
}

CLI Package

{
  "name": "@kyrage/cli",
  "dependencies": {
    "@kyrage/core": "workspace:*"
  },
  "optionalDependencies": {
    "@kyrage/dialect-postgres": "workspace:*",
    "@kyrage/dialect-cockroachdb": "workspace:*",
    "@kyrage/dialect-duckdb": "workspace:*"
  }
}

Dialect Packages

// @kyrage/dialect-postgres
{
  "name": "@kyrage/dialect-postgres",
  "dependencies": {
    "@kyrage/core": "workspace:*",
    "kysely": "^0.27.0",
    "pg": "^8.0.0",
    "@testcontainers/postgresql": "^10.0.0"
  }
}

// @kyrage/dialect-duckdb
{
  "name": "@kyrage/dialect-duckdb", 
  "dependencies": {
    "@kyrage/core": "workspace:*",
    "kysely": "^0.27.0",
    "@oorabona/kysely-duckdb": "^2.0.0",
    "@duckdb/node-api": "^1.0.0"
  }
}

Meta Package

{
  "name": "@kyrage/kyrage",
  "dependencies": {
    "@kyrage/cli": "workspace:*",
    "@kyrage/dialect-postgres": "workspace:*", 
    "@kyrage/dialect-cockroachdb": "workspace:*",
    "@kyrage/dialect-duckdb": "workspace:*"
  }
}

🎯 Expected Benefits

For Users

  • Smaller Bundle Size: Install only required dialects
  • Faster Installation: Fewer dependencies to download
  • Cleaner Dependencies: No unused database drivers
  • Same Developer Experience: Existing workflows unchanged

For Maintainers

  • Independent Development: Dialect packages can be developed in parallel
  • Focused Testing: Each dialect has its own test suite
  • Easier Releases: Independent versioning per dialect
  • Community Extensions: Third-party dialects become possible

For Ecosystem

  • Plugin Architecture: Foundation for community-contributed dialects
  • Reduced Barrier to Entry: New dialects don't require core changes
  • Better Performance: Runtime loading only what's needed

This design maintains full backward compatibility while providing a foundation for extensible, maintainable dialect support that can grow with the community's needs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions