Back to Blog
Tutorial9 min read2026-06-30

How to Deploy an Elysia Bun API with PostgreSQL

Elysia is a Bun-first framework with end-to-end type safety and excellent performance. This guide covers building a Bun container, connecting PostgreSQL, and deploying an Elysia API to production.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Elysia is a web framework built specifically for Bun, leaning into Bun's speed and TypeScript-first design. It offers Express-like ergonomics with end-to-end type safety (its Eden client gives you typed API calls). Deploying it means running Bun in a container — fast startup, small footprint, minimal ceremony.

A typed Elysia API

bun add elysia
// src/index.ts
import { Elysia, t } from 'elysia';

const app = new Elysia()
  .get('/health', () => ({ status: 'ok' }))
  .get('/api/posts/:id', ({ params }) => ({ id: params.id }), {
    params: t.Object({ id: t.String() })
  })
  .listen({ port: Number(process.env.PORT ?? 3000), hostname: '0.0.0.0' });

console.log(`elysia on :${app.server?.port}`);

The t schema validators give you runtime validation *and* static types from one definition — that's Elysia's core appeal. Binding to 0.0.0.0 is required so the platform proxy can reach the server inside the container.

Connecting PostgreSQL

Bun ships a native, fast SQL client, but for a stable API the postgres (postgres.js) library works great and is widely used:

import postgres from 'postgres';

const sql = postgres(process.env.DATABASE_URL!, { max: 10 });

app.get('/api/posts', async () => {
  return await sql`SELECT * FROM posts LIMIT 20`;
});

Alternatively, Bun's built-in Bun.sql / bun:sqlite and Drizzle ORM all work; pick what your team knows. Keep the pool modest (max: 10) and sized under your database's connection limit across all replicas.

Containerize with the official Bun image

Bun's official image makes this trivial. The key optimization is bun install --frozen-lockfile in its own layer for cache reuse:

FROM oven/bun:1 AS deps
WORKDIR /app
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile --production

FROM oven/bun:1
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NODE_ENV=production
EXPOSE 3000
CMD ["bun", "run", "src/index.ts"]

No transpile step needed — Bun runs TypeScript directly. That keeps the image lean and cold starts quick.

Optional: compile to a single binary

Bun can compile your app to a standalone executable, which trims startup further:

bun build src/index.ts --compile --outfile server

Then CMD ["./server"]. This is great for scale-to-zero where every millisecond of cold start counts.

Deploying on PandaStack

  1. 1Provision a managed PostgreSQL (14.x or 16.x). PandaStack injects DATABASE_URL; postgres.js reads it directly.
  2. 2Connect the Git repo as a container app. The Dockerfile is auto-detected; Bun is also supported as a runtime/install option if you skip the Dockerfile.
  3. 3Set NODE_ENV=production. The platform provides PORT; the code already reads it.
  4. 4Add a custom domain; SSL is automatic.

Bun's fast startup is a genuine advantage on scale-to-zero tiers — the first request after idle pays a smaller cold-start penalty than a heavier Node stack. For consistently low latency on production traffic, run on always-on compute.

Production notes

  • Validation everywhere: use Elysia's t schemas on params, query, and body — you get both safety and OpenAPI generation via the Swagger plugin.
  • Graceful shutdown: handle SIGTERM to close the SQL pool before exit.
  • Eden client: if you have a TypeScript frontend, Elysia's Eden gives typed calls without codegen — share the app type.
process.on('SIGTERM', async () => {
  await sql.end();
  process.exit(0);
});

Verifying

curl -s https://api.example.com/health
# {"status":"ok"}

curl -s https://api.example.com/api/posts | head

Healthy responses plus real rows confirm Bun and PostgreSQL are wired correctly.

References

  • [Elysia documentation](https://elysiajs.com/)
  • [Bun official Docker guide](https://bun.sh/guides/ecosystem/docker)
  • [Bun single-file executables](https://bun.sh/docs/bundler/executables)
  • [postgres.js (postgres npm)](https://github.com/porsager/postgres)

---

Elysia on Bun is a small, fast container that scale-to-zero loves — and PandaStack supports Bun natively while injecting DATABASE_URL from a managed PostgreSQL. Start free at [dashboard.pandastack.io](https://dashboard.pandastack.io).

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also