npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@onebun/drizzle

v0.2.0

Published

Drizzle ORM module for OneBun framework - SQLite and PostgreSQL support

Readme

@onebun/drizzle

Drizzle ORM module for OneBun framework with support for SQLite and PostgreSQL.

Features

  • Schema-First Approach: Drizzle table schemas (pgTable/sqliteTable) are the single source of truth
  • Type Safety: Automatic type inference from schemas using $inferSelect and $inferInsert
  • Migrations: Automatic migration generation and application using drizzle-kit
  • Repository Pattern: BaseRepository class for common CRUD operations
  • Future-Ready: Compatible with drizzle-arktype for validation

Installation

bun add @onebun/drizzle drizzle-orm drizzle-kit

Quick Start

1. Define Your Schema

Create a schema file using Drizzle's pgTable (for PostgreSQL) or sqliteTable (for SQLite). Choose the function that matches your database type configured in step 2.

For PostgreSQL:

// src/schema/users.ts
import { pgTable, text, integer, timestamp } from 'drizzle-orm/pg-core';

export const users = pgTable('users', {
  // Use generatedAlwaysAsIdentity() for auto-increment primary key
  id: integer('id').primaryKey().generatedAlwaysAsIdentity(),
  name: text('name').notNull(),
  email: text('email').notNull().unique(),
  age: integer('age'),
  createdAt: timestamp('created_at', { mode: 'date' }).notNull().defaultNow(),
  updatedAt: timestamp('updated_at', { mode: 'date' }).notNull().defaultNow(),
});

// Extract types from schema
export type User = typeof users.$inferSelect;
export type InsertUser = typeof users.$inferInsert;

For SQLite:

// src/schema/users.ts
import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';

export const users = sqliteTable('users', {
  id: integer('id').primaryKey({ autoIncrement: true }),
  name: text('name').notNull(),
  email: text('email').notNull().unique(),
  age: integer('age'),
  createdAt: integer('created_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
  updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
});

// Extract types from schema
export type User = typeof users.$inferSelect;
export type InsertUser = typeof users.$inferInsert;

2. Configure the Module

Choose your database type (PostgreSQL or SQLite) and configure the module accordingly. This choice determines which table function (pgTable or sqliteTable) you'll use in your schemas.

For PostgreSQL:

// src/app.module.ts
import { Module } from '@onebun/core';
import { DrizzleModule, DatabaseType } from '@onebun/drizzle';

@Module({
  imports: [
    DrizzleModule.forRoot({
      connection: {
        type: DatabaseType.POSTGRESQL,
        options: {
          host: 'localhost',
          port: 5432,
          user: 'postgres',
          password: 'password',
          database: 'mydb',
        },
      },
      autoMigrate: true,
      migrationsFolder: './drizzle',
    }),
  ],
})
export class AppModule {}

For SQLite:

// src/app.module.ts
import { Module } from '@onebun/core';
import { DrizzleModule, DatabaseType } from '@onebun/drizzle';

@Module({
  imports: [
    DrizzleModule.forRoot({
      connection: {
        type: DatabaseType.SQLITE,
        options: {
          url: './mydb.sqlite', // or ':memory:' for in-memory database
        },
      },
      autoMigrate: true,
      migrationsFolder: './drizzle',
    }),
  ],
})
export class AppModule {}

4. Create a Repository

The repository works seamlessly with your schema, regardless of whether you're using PostgreSQL or SQLite. No database-specific checks needed!

// src/repositories/user.repository.ts
import { eq } from 'drizzle-orm';
import { BaseRepository, Entity } from '@onebun/drizzle';
import type { DrizzleService } from '@onebun/drizzle';
import { users } from '../schema/users';

@Entity(users)
export class UserRepository extends BaseRepository<typeof users> {
  // Add custom business logic methods here
  // No need to check database type - just work with the schema!
  async findByEmail(email: string) {
    const db = this.getDb();
    const table = this.getTable();
    
    // Type assertion needed because db has union type, but Drizzle provides unified API
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const results = await (db as any)
      .select()
      .from(table)
      .where(eq(table.email, email));
    
    return results[0] || null;
  }
}

5. Generate Migrations

import { generateMigrations } from '@onebun/drizzle';

await generateMigrations({
  schemaPath: './src/schema',
  migrationsFolder: './drizzle',
  dialect: 'postgresql',
});

Schema-First Approach

This module uses a schema-first approach where Drizzle table schemas are the single source of truth:

  • Table Definition: Defined using pgTable() for PostgreSQL or sqliteTable() for SQLite
  • TypeScript Types: Extracted using $inferSelect and $inferInsert
  • Migrations: Generated automatically by drizzle-kit from schemas
  • Validation: Ready for integration with drizzle-arktype (future)

Key Principles

  1. Choose Database Type Once: When initializing the module, choose either PostgreSQL or SQLite
  2. Use Matching Table Function: Use pgTable() if using PostgreSQL, sqliteTable() if using SQLite
  3. No Database-Specific Code: Repositories and services work with schemas directly - no isSQLite() or isPostgreSQL() checks needed
  4. Single Source of Truth: The schema defines everything - table structure, types, and migrations

Benefits

  1. No Code Duplication: Define your table once, get types and migrations automatically
  2. Type Safety: Full TypeScript support with inferred types
  3. Migration Safety: Drizzle-kit tracks applied migrations automatically
  4. Clean API: No database-specific checks in your business logic
  5. Future-Proof: Easy to add validation with arktype later

Migration Management

Automatic Migrations

Set autoMigrate: true in module options to automatically apply migrations on startup:

DrizzleModule.forRoot({
  connection: { /* ... */ },
  autoMigrate: true,
  migrationsFolder: './drizzle',
})

Drizzle-kit automatically tracks applied migrations in the __drizzle_migrations table, preventing double application.

Manual Migration Generation

import { generateMigrations } from '@onebun/drizzle';

// Generate migration files
await generateMigrations({
  schemaPath: './src/schema',
  migrationsFolder: './drizzle',
  dialect: 'postgresql',
});

Integration with ArkType (Future)

This module is designed to be compatible with drizzle-arktype for runtime validation:

import { createSelectSchema, createInsertSchema } from 'drizzle-arktype';
import { users } from './schema/users';

// Generate validation schemas from Drizzle schemas
const userSelectSchema = createSelectSchema(users);
const userInsertSchema = createInsertSchema(users);

// Use for API request/response validation
const validatedData = userInsertSchema.parse(requestBody);

API Reference

BaseRepository

Base class for repositories providing CRUD operations:

class BaseRepository<TTable extends PgTable<any> | SQLiteTable<any>> {
  findAll(): Promise<SelectType<TTable>[]>;
  findById(id: unknown): Promise<SelectType<TTable> | null>;
  create(data: Partial<InsertType<TTable>>): Promise<SelectType<TTable>>;
  update(id: unknown, data: Partial<InsertType<TTable>>): Promise<SelectType<TTable> | null>;
  delete(id: unknown): Promise<boolean>;
  count(): Promise<number>;
  transaction<R>(callback: (tx) => Promise<R>): Promise<R>;
}

Schema Utilities

Helper functions for working with schemas:

import { SelectType, InsertType, getTableName, getPrimaryKeyColumn } from '@onebun/drizzle';

// Extract types
type User = SelectType<typeof users>;
type InsertUser = InsertType<typeof users>;

// Get metadata
const tableName = getTableName(users); // 'users'
const pkColumn = getPrimaryKeyColumn(users); // 'id'

Examples

See tests/integration/ for complete examples including:

  • Schema definition
  • Repository implementation
  • Service layer
  • Controller endpoints
  • Integration tests

Environment Variables

DB_TYPE=postgresql          # 'sqlite' or 'postgresql'
DB_URL=postgresql://...    # Connection URL
DB_SCHEMA_PATH=./src/schema
DB_MIGRATIONS_FOLDER=./drizzle
DB_AUTO_MIGRATE=true
DB_LOG_QUERIES=false

License

LGPL-3.0