โ† Back to news

Show HN: Bun-sqlgen โ€“ Type-safe raw SQL for Bun, no ORM

github.com|43 points|21 comments|by ilbert|Jun 23, 2026

Introducing bun-sqlgen: Type-Safe Raw SQL for Bun

bun-sqlgen is a specialized type generator designed for Bun.sql queries. It allows developers to write raw SQL while maintaining strict type safety without the overhead of a full ORM.

The Core Philosophy: Why choose between the power of raw SQL and the safety of TypeScript? bun-sqlgen bridges this gap by live-checking your queries against your actual database schema.


๐Ÿš€ Key Features & Benefits

Instead of relying on heavy ORMs or manually writing interfaces, bun-sqlgen automates the process.

  • Zero-Effort Typing: Tag a query (e.g., sql.GetUser) and get fully-typed, null-safe results immediately.
  • No Generics: You don't have to pass complex generic types to your query functions.
  • Real-World Validation: The codegen process validates queries against a live Postgres or SQLite instance.
  • Fast Feedback Loop: It is optimized to run on every file save, ensuring that bad SQL or missing columns fail during the build phase rather than in production.
  • Lightweight: No Docker containers are required for the validation process.

Database Compatibility

DatabaseSupportedRequirement
PostgreSQLโœ…Real instance for validation
SQLiteโœ…Real instance for validation

๐Ÿ› ๏ธ Workflow Architecture

The following diagram illustrates how bun-sqlgen transforms your SQL migrations into TypeScript definitions:


๐Ÿ“– Quick Start Guide

1. Installation

Add the package to your project using the Bun package manager: bun add @ilbertt/bun-sqlgen

2. Setup Checklist

  • Create a migrations folder (e.g., db/migrations/).
  • Define your schema in .sql files.
  • Wrap your Bun SQL client.
  • Run the generator.

3. Implementation Example

Step A: Define your schema In db/migrations/0001_init.sql:

CREATE TABLE users (
  id bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  email text NOT NULL,
  display_name text
);

Step B: Write your typed query

import { withTypes } from '@ilbertt/bun-sqlgen';
import { SQL } from 'bun';

// Wrap the standard Bun SQL client
const sql = withTypes(new SQL(Bun.sql));

export async function getUser(id: number) {
  // Tag the query with .GetUser to trigger type generation
  const [user] = await sql.GetUser`
    SELECT id, email, display_name 
    FROM users 
    WHERE id = ${id}
  `;
  
  return user; 
  // Result is automatically typed as: 
  // { id: string; email: string; display_name: string | null }
}

Step C: Generate the types Run the following command in your terminal:

bun bun-sqlgen generate 'src/**/*.ts' --migrations db/migrations

This process creates a src/queries.gen.d.ts file. Note: This file should be committed to your version control.


๐Ÿ” Technical Nuances

The mapping of database types to TypeScript can be represented as a function: Schema(Column)โ†’TypeScript(Typeโˆชnull)\text{Schema}(\text{Column}) \rightarrow \text{TypeScript}(\text{Type} \cup \text{null})

Because the tool checks the actual schema, if you attempt to access user.emial (a typo), tsc will throw a compile error. Similarly, because display_name is nullable in the database, TypeScript will flag user.display_name.length as a potential error unless you handle the null case.

Bun-sqlgen Logo Placeholder

๐Ÿค Contributing & Project Info

  • Language: 100% TypeScript.
  • License: Unlicense.
  • Documentation: Detailed guides on transactions, nullability overrides, and configuration are available in the main README.
  • Guidelines: Please refer to CONTRIBUTING.md for development setup and conventions.