Skip to content

Installation

Bun 1.4 or newer. Oven is Bun-only by design — it uses Bun.serve, Bun.file, Bun.S3Client, Bun.Image and bun:sqlite directly rather than abstracting over them, which is what keeps the framework small and fast. There is no Node build and no plan for one.

Terminal window
bun --version # 1.2.0 or higher
Terminal window
bun create theoven my-app
cd my-app
bun install
bun run dev

The scaffolder asks what you want and writes a configured, working app — no copy-pasted boilerplate. Answer with flags instead if you prefer:

Terminal window
bun create theoven my-app --db sqlite --auth basic --yes
Flag Values
--template minimal, api api starts with a small REST API
--db sqlite, postgres, none SQLite is Drizzle over bun:sqlite — no server to run
--auth basic, none eight working endpoints at /auth/*
--no-openapi skip the OpenAPI brick and /docs
--yes accept every default

With a database, run the migrations the scaffold printed before starting:

Terminal window
cp .env.example .env
bun run db:generate && bun run db:migrate
bun run dev
Terminal window
bun add @theoven/core
bun add -d @theoven/cli
src/app.ts
import { createApp, loadRoutes } from '@theoven/core'
export const app = createApp()
await loadRoutes(app, `${import.meta.dir}/routes`)
export default app
src/index.ts
import app from './app'
await app.listen(3000)

Keep listen() out of app.ts. That split is what lets oven routes, oven openapi, oven worker and your tests import the app without binding a port.

Then add whichever bricks you need — each is one bun add and one .use().

Bun loads .env, .env.local and .env.<NODE_ENV> on its own, so there is nothing to install. Read them safely with env.*, or validate the whole set at boot with defineEnv — see Environment variables.

import { env } from '@theoven/core'
const port = env.port('PORT', 3000)

A missing variable then fails at startup, naming itself, rather than at 3am as undefined somewhere unrelated.

Oven’s test suite is the contract. Run it first, so you know a failure is yours:

Terminal window
git clone https://github.com/hiteshchoudhary/theoven.git
cd theoven
bun install
bun test # every package
bun run lint # Biome
bun run typecheck
bun run check:docs # every code sample on this site

examples/kitchen-sink registers every brick in one app and is the framework’s integration test — if a change breaks how two bricks compose, it breaks there.

Your first route →