Skip to main content

Kysera

Production-ready type-safe data access toolkit built on top of Kysely with zero compromises on reliability, type safety, and performance.

What is Kysera?

Kysera is a lightweight, modular data access toolkit that builds upon Kysely - the type-safe SQL query builder. Kysera is NOT a traditional ORM - it has no entity mapping, Unit of Work, Identity Map, or lazy loading. Instead, it provides lightweight patterns and plugins on top of Kysely:

  • Unified Execution Layer (@kysera/executor) - Foundation for plugin interception across all query patterns
  • Repository Pattern with validation-agnostic design (Zod, Valibot, TypeBox, or native)
  • Functional DAL for type-inferred queries and context-based transactions
  • Plugin System for extensibility (soft delete, audit, timestamps, RLS) that works with both Repository and DAL
  • Infrastructure Utilities (health checks, retry, circuit breaker) as opt-in packages
  • Zero External Dependencies in core packages
  • Full TypeScript with strict mode support
  • Cross-Runtime Compatibility - Node.js >=20.0.0, Bun >=1.0.0, Deno (experimental)

Philosophy

"Start minimal, grow as needed, stay transparent."

Core Principles

  1. Minimal Core, Optional Everything

    • Core contains only essential utilities (~8KB): errors, pagination, types, logger
    • Infrastructure (health, retry, shutdown) is a separate opt-in package
    • Repository pattern is optional
    • All features are opt-in plugins
    • Tree-shakeable ESM architecture
  2. Explicit Over Implicit

    • Every operation is traceable
    • No hidden context propagation
    • Transaction boundaries are clear
    • No automatic behaviors
  3. Validation-Agnostic Design

    • Use any validation library: Zod, Valibot, TypeBox, or none
    • ValidationSchema adapter interface for library independence
    • Backward compatible with existing Zod schemas
  4. Dual API Approach

    • Repository Pattern: CRUD operations with validation for structured access
    • Functional DAL: Type-inferred queries with context passing for complex operations
  5. Production-First Design

    • Health checks via @kysera/infra (opt-in)
    • Graceful shutdown support
    • Circuit breaker and retry logic
    • Comprehensive error handling

Package Overview

Core Packages

PackageDescriptionSize
@kysera/coreError handling, pagination, types, logger~8KB
@kysera/executorUnified Execution Layer (plugin foundation)~6KB
@kysera/repositoryRepository pattern with validation adapters~12KB
@kysera/dalFunctional Data Access Layer~7KB

Infrastructure Packages (Opt-in)

PackageDescriptionSize
@kysera/infraHealth checks, retry, circuit breaker, shutdown~12KB
@kysera/debugQuery logging, profiling, SQL formatting~5KB
@kysera/testingTest utilities (transaction rollback, factories)~6KB
@kysera/migrationsMigration system with dry-run support~11KB

Plugins

PackageDescriptionSize
@kysera/soft-deleteSoft delete plugin~4KB
@kysera/auditAudit logging plugin~11KB
@kysera/timestampsAutomatic timestamps plugin~4KB
@kysera/rlsRow-level security plugin~44KB

Architecture

Layer 5: Plugins (@kysera/soft-delete, @kysera/audit, @kysera/timestamps, @kysera/rls)

Layer 4: Data Access (@kysera/repository OR @kysera/dal - choose your style)

Layer 3: Unified Execution (@kysera/executor - plugin interception foundation)

Layer 2: Infrastructure (@kysera/infra, @kysera/debug, @kysera/testing - opt-in)

Layer 1: Core Utilities (@kysera/core - minimal)

Layer 0: Kysely Foundation (Direct usage, no wrapper)

Quick Example

Repository Pattern with Plugins

import { Kysely, PostgresDialect, Generated } from 'kysely'
import { Pool } from 'pg'
import { createExecutor } from '@kysera/executor'
import { createORM, zodAdapter } from '@kysera/repository'
import { softDeletePlugin } from '@kysera/soft-delete'
import { timestampsPlugin } from '@kysera/timestamps'
import { z } from 'zod'

// Define schema
interface Database {
users: {
id: Generated<number>
email: string
name: string
created_at: Generated<Date>
updated_at: Generated<Date>
deleted_at: Date | null
}
}

// Create connection
const db = new Kysely<Database>({
dialect: new PostgresDialect({ pool: new Pool({ connectionString: '...' }) })
})

// Create executor with plugins (foundation layer)
const executor = await createExecutor(db, [
softDeletePlugin(),
timestampsPlugin()
])

// Create ORM (plugin container, not traditional ORM)
const orm = await createORM(executor, [])

// Create repository
const userRepo = orm.createRepository(exec => {
const factory = createRepositoryFactory(exec)
return factory.create({
tableName: 'users',
mapRow: row => row,
schemas: {
create: zodAdapter(z.object({ email: z.string().email(), name: z.string() })),
update: zodAdapter(z.object({ email: z.string().email(), name: z.string() }).partial())
}
})
})

// Use repository - plugins apply automatically
const user = await userRepo.create({ email: 'john@example.com', name: 'John' })
// created_at, updated_at set automatically by timestampsPlugin

await userRepo.softDelete(user.id) // Sets deleted_at instead of hard delete
const activeUsers = await userRepo.findAll() // Automatically excludes soft-deleted

Functional DAL with Plugins

import { createQuery, createContext, withTransaction } from '@kysera/dal'

// Define queries
const getUser = createQuery((ctx, id: number) =>
ctx.db.selectFrom('users').where('id', '=', id).selectAll().executeTakeFirst()
)

const listActiveUsers = createQuery((ctx) =>
ctx.db.selectFrom('users').selectAll().execute()
)

// Create context with executor (plugins apply automatically)
const ctx = createContext(executor)

// Queries automatically filtered by soft-delete plugin
const user = await getUser(ctx, 1) // Returns null if soft-deleted
const users = await listActiveUsers(ctx) // Excludes soft-deleted records

// Transactions preserve plugins
await withTransaction(executor, async (txCtx) => {
const user = await getUser(txCtx, userId)
// All queries in transaction have plugin filters
})

Requirements

  • Runtime: Node.js >=20.0.0, Bun >=1.0.0, or Deno (experimental)
  • TypeScript: ^5.9.2 (recommended for best type inference)
  • Kysely: >=0.28.9 (peer dependency)
  • Validation library (optional): Zod ^4.1.13, Valibot, TypeBox, or none
  • Module System: ESM-only (no CommonJS)

Database Support

  • PostgreSQL
  • MySQL
  • SQLite
  • MSSQL (SQL Server)

Next Steps