PAS7 Studio
Illustration von Bun.js, Elysia, Drizzle und PostgreSQL
Technologie27. Aug. 2026·3 Min. Lesezeit·Aktualisiert 27. Aug. 2026

Bun.js + Elysia + Drizzle: eine typsichere REST-API mit PostgreSQL

Ein praktisches Bun.js-API mit Elysia für Routing, Drizzle ORM für typisierte SQL-Abfragen, PostgreSQL und Zod-Validierung.

TypeScript-EntwicklerFull-Stack-TeamsAPI- und Microservice-Teams

Elysia verarbeitet HTTP-Routen, Drizzle beschreibt PostgreSQL-Tabellen mit TypeScript und Bun führt den gesamten Service ohne separaten Transpilierungsschritt aus.

Schema und Anwendungstypen stammen aus einer Quelle.
Ungültige Payloads werden vor SQL abgelehnt.
Migrationen bleiben in CI und Produktion reproduzierbar.
Xin

Warum dieser Stack

Jede Bibliothek hat eine klare Aufgabe — das hält den Service testbar und erweiterbar.

Elysia

Ein Bun-natives HTTP-Framework mit Routen, Middleware und Schemas.

Drizzle

Ein SQL-first ORM: Tabellen sind TypeScript, Abfragen bleiben nah an SQL.

PostgreSQL

Ein zuverlässiges Production-Storage für Indizes, Transaktionen und Wachstum.

Zod

Validiert Eingaben an der API-Grenze vor der Service-Schicht.

Die Anfrage wird vor SQL validiert; die Antwort folgt einem typisierten Vertrag.

Screenshot des Abschnitts stack

Schritt 1: Projekt erstellen

Bun installiert Abhängigkeiten und führt TypeScript ohne separaten Bundler aus.

01

Initialisieren

BASH
mkdir tasks-api && cd tasks-api
bun init
bun add elysia drizzle-orm postgres zod
bun add -d drizzle-kit
02

Umgebung konfigurieren

ENV
DATABASE_URL=postgres://app:app@localhost:5432/tasks
PORT=3000
DB_POOL_SIZE=10

Bun lädt .env automatisch. Geheimnisse gehören nicht ins Repository.

03

Migrationen konfigurieren

TS
import { defineConfig } from "drizzle-kit";
export default defineConfig({ schema: "./src/db/schema.ts", out: "./drizzle", dialect: "postgresql", dbCredentials: { url: process.env.DATABASE_URL! } });

Danach bun run db:generate und bun run db:migrate ausführen.

Schritt 2: Tabelle und Migration definieren

Die Tabelle ist die Quelle für Insert- und Select-Typen. Einen zweiten manuellen Task-Typ sollten wir vermeiden.

TS
import { boolean, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
export const tasks = pgTable("tasks", { id: uuid("id").defaultRandom().primaryKey(), title: text("title").notNull(), done: boolean("done").notNull().default(false), createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull() });
export type Task = typeof tasks.$inferSelect;
export type NewTask = typeof tasks.$inferInsert;

Die generierte Migration wird mit bun run db:migrate angewendet.

Schritt 3: typsichere Elysia-Routen

Elysia validiert Payloads am Rand der Anwendung. Der Handler kann sich dadurch auf die Datenbankoperation konzentrieren.

TS
import { Elysia, t } from "elysia";
import { desc, eq } from "drizzle-orm";
import { db } from "./db/client";
import { tasks } from "./db/schema";
export const app = new Elysia()
  .get("/health", () => ({ status: "ok", runtime: "bun" }))
  .get("/tasks", () => db.select().from(tasks).orderBy(desc(tasks.createdAt)))
  .patch("/tasks/:id", async ({ params, body }) => { const [task] = await db.update(tasks).set({ done: body.done }).where(eq(tasks.id, params.id)).returning(); return task ?? new Response("Nicht gefunden", { status: 404 }); }, { params: t.Object({ id: t.String() }), body: t.Object({ done: t.Boolean() }) })
  .listen(Number(Bun.env.PORT ?? 3000));

Database Client und Docker Compose

Erzeuge einen Pool pro langlebigem Bun-Prozess. Compose stellt lokal für das ganze Team dieselbe PostgreSQL-Version bereit.

TS
import postgres from "postgres";
import { drizzle } from "drizzle-orm/postgres-js";
const sql = postgres(Bun.env.DATABASE_URL!, { max: Number(Bun.env.DB_POOL_SIZE ?? 10), prepare: false });
export const db = drizzle(sql);
YAML
services:
  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
      POSTGRES_DB: tasks
    ports: ["5432:5432"]

Transaktionen, Fehler und Production-Regeln

Ein schneller Runtime ersetzt keine klaren Datengrenzen.

Transaktionen für verbundene Writes

Mehrere Tabellen mit db.transaction(async (tx) => { ... }) atomar ändern.

404 für fehlende Ressourcen

Das Ergebnis von returning() prüfen und nicht undefined mit 200 senden.

Migrationen separat ausführen

Migrationen als Deploy-Schritt anwenden, nicht aus jeder Server-Instanz.

Pool begrenzen

In Serverless-Umgebungen Pooler oder niedrigere Limits verwenden.

Handler ohne offenen Port testen

Mit handle lässt sich die Anwendung direkt testen.

TS
import { expect, test } from "bun:test";
import { app } from "./index";
test("lehnt einen leeren Titel ab", async () => {
  const response = await app.handle(new Request("http://localhost/tasks", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ title: "  " }) }));
  expect(response.status).toBe(422);
});

Mit bun test gegen eine eigene Testdatenbank ausführen.

Lokal ausführen und testen

01

PostgreSQL starten

BASH
docker compose up -d
bun run db:migrate
02

Bun starten

BASH
bun run src/index.ts
curl http://localhost:3000/health
03

Lockfile verwenden

BASH
bun install --frozen-lockfile
bun run db:migrate
bun test
FAQ

FAQ

Funktioniert Drizzle mit Bun?

Ja. Drizzle funktioniert mit Bun und PostgreSQL über den postgres-Treiber oder einen unterstützten Treiber. Die verwendeten Versionen sollten im Deployment getestet werden.

Braucht Elysia Node.js?

Nein. Bun stellt Runtime, Package Manager und TypeScript-Ausführung bereit.

Geprüft: 27. Aug. 2026Gilt für: Bun 1.3+Gilt für: Elysia 1.xGilt für: Drizzle ORM 0.44+Gilt für: PostgreSQL 16+Getestet mit: Bun runtimeGetestet mit: ElysiaGetestet mit: drizzle-kitGetestet mit: PostgreSQL mit Docker

Fazit

Beschreiben Sie die Aufgabe — die ersten 15 Minuten der Beratung sind kostenlos.

Verwandte Artikel

AI Assistant Entwicklung Kosten 2026: RAG, Knowledge Base, Integrationen und Support
ai-assistants

AI Assistant Entwicklung Kosten 2026: RAG, Knowledge Base, Integrationen und Support

Praktischer Leitfaden zu Kosten fuer AI Assistants: RAG, Knowledge Base, Channels, Tool Use, Guardrails, Evaluations, Monitoring und Support.

KI fur Landingpage-Entwicklung: wo sie Launches beschleunigt und wo sie Conversion schadet
blogs

KI fur Landingpage-Entwicklung: wo sie Launches beschleunigt und wo sie Conversion schadet

Eine praxisnahe Analyse zur Nutzung von KI fur Landingpages: v0, Webflow AI, Builder.io, Framer-ahnliche Builder, UX-Generierung, Copy, SEO, Personalisierung, A/B-Tests, Template-Risiken, Accessibility, Security und technischer Schuldenaufbau.

AI SEO / GEO im Jahr 2026: Ihre nächsten Kunden sind nicht Menschen — sondern Agents
growth

AI SEO / GEO im Jahr 2026: Ihre nächsten Kunden sind nicht Menschen — sondern Agents

Suche verschiebt sich von Klicks zu Antworten. Bots und AI-Agents crawlen, zitieren, empfehlen — und kaufen zunehmend. Erfahren Sie, was AI SEO / GEO bedeutet, warum klassisches SEO nicht mehr reicht und wie PAS7 Studio Marken im agentischen Web sichtbar macht.

Der leistungsstärkste Chip von Apple? M5 Pro und M5 Max brechen Rekorde
blogs

Der leistungsstärkste Chip von Apple? M5 Pro und M5 Max brechen Rekorde

Eine Analyse zu Apple M5 Pro und M5 Max im März 2026. Wir zeigen, warum diese Chips als die stärksten professionellen Laptop-SoCs von Apple gelten können, wie sie sich gegen M4 Pro, M4 Max, M1 Pro, M1 Max schlagen und was der Vergleich mit aktuellen Intel- und AMD-Chips zeigt.

Professionelle Entwicklung für Ihr Geschäft

Wir erstellen moderne Web-Lösungen und Bots für Unternehmen. Erfahren Sie, wie wir Ihnen helfen können, Ihre Ziele zu erreichen.