Skip to content
hiteshchoudharyPublic

About

A modern bun framework that is easy and AI first

Resources

Stars

74 stars

Watchers

0 watching

Forks

Repository files navigation

Oven

The batteries-included Bun framework.
Express-simple. FastAPI-smart. Everything configurable.

npm docs MIT

bun create theoven my-app --db sqlite --auth basic

That gives you a working app with a database, signup, login and password reset — before you have provisioned anything at all.

The idea

Every backend needs the same things: auth, a database, file storage, email, background jobs. Every backend wires them by hand, badly, again.

Oven makes each one a brick. Add it, and you get a small, obvious, fully-typed API on the request context — and the type only exists if you added it.

import { createApp } from '@theoven/core'
import { auth } from '@theoven/auth'
import { basicAuth } from '@theoven/auth-basic'
import { db } from '@theoven/db'
import { drizzleSqlite } from '@theoven/db-drizzle'
import { storage, s3Storage } from '@theoven/storage'

export const app = createApp()
  .use(db(drizzleSqlite({ url: './data.db', schema })))
  .use(auth(basicAuth({ db: client, secret: process.env.AUTH_SECRET! })))
  .use(storage(s3Storage({ bucket: 'uploads' })))
import { z } from 'zod'
import { route } from '../../../route'

export default route(
  {
    auth: true,
    params: z.object({ id: z.uuid() }),
    body: z.object({ file: z.file().max(5_000_000) }),
    response: { 200: z.object({ id: z.uuid(), avatar: z.string() }) },
  },
  async (ctx) => {
    const { key } = await ctx.storage.upload(`avatars/${ctx.params.id}`, ctx.body.file)
    return ctx.db.update(users).set({ avatar: key }).where(eq(users.id, ctx.params.id)).returning()
  },
)

Validated, authenticated, typed, and documented at /docs. Nothing wired by hand.

The response schema is not only documentation — it filters the body, so a column the schema does not declare cannot be sent even when the handler returns the whole row.

What is in the box

Always on, nothing to install, nothing to order, nothing to forget:

Replaces
Body parsing JSON, urlencoded, multipart, text, raw — content-type aware body-parser
File uploads web File objects, size and MIME limits multer
Cookies ctx.cookies, signed, secure by default outside development cookie-parser
Query parsing arrays and nested keys qs
Token capture Authorization, cookie, or ?access_token= hand-rolled
Request id + logging structured, request-scoped morgan + uuid
Errors RFC 9457 problem+json; async errors caught express-async-errors
Graceful shutdown SIGTERM drains in flight, then closes bricks hand-rolled

CORS, rate limiting, compression and security headers ship configured rather than installed.

Packages

Core

Package
@theoven/core router, context, validation, OpenAPI, WebSockets, SSE, routers, dependencies
@theoven/cli oven dev, build, routes, db, worker, doctor
create-theoven bun create theoven my-app

Contracts and adapters — a small interface package, many implementations

Contract Adapters
@theoven/db db-drizzle (SQLite, Postgres) · db-mongoose
@theoven/auth auth-basic (SQL) · auth-mongo · auth-clerk · auth-better
@theoven/storage S3, disk · storage-bunny · storage-imagekit

Standalone bricks

Package
@theoven/mail Resend, SES, SMTP, and a dev preview inbox
@theoven/queue jobs, retries, backoff, dead letter, cron — memory, Redis or Postgres
@theoven/cache tag invalidation and stampede protection — memory or Redis
@theoven/telemetry OpenTelemetry spans named by route pattern
@theoven/webhooks signature verification for inbound deliveries, with replay windows
@theoven/ratelimit counting that holds across instances, atomically — Redis or Postgres
@theoven/vector one contract over an embedded scan · vector-pg · vector-qdrant
@theoven/ai SSE streaming, caching, token accounting and budgets around the AI SDK
@theoven/image resize, convert and guard uploads on Bun.Image — no native module

Beyond the batteries

// Group routes: one prefix, one tag, one guard.
const admin = routerFor<typeof app>({ prefix: '/admin', tags: ['admin'], auth: 'staff' })
admin.get('/users', (ctx) => ctx.db.select().from(users))
app.use(admin)
// A per-request value that composes and cleans up after itself.
const tx = dependency('tx', async function* (ctx) {
  const handle = await begin(ctx.db)
  try {
    yield handle
    await handle.commit()
  } catch (error) {
    await handle.rollback()
    throw error
  }
})

export default route({ deps: { tx } }, async (ctx) => {
  await ctx.deps.tx.insert(orders).values(order)
  return { ok: true }
})

Also in core: WebSockets upgraded from an ordinary guarded route, server-sent events, and an OpenAPI document generated from the schemas you already wrote.

Docs

theoven.app/docs

Status

0.6.1, on npm. Core, the CLI and twenty-two bricks are published and installable.

Pre-1.0, so APIs can still change between minor versions — that freedom is deliberate while the contracts settle. See CHANGELOG.md for what each release changed.

  • On 0.1.2 or earlier — upgrade. A route file declaring export const auth = true was not guarded and answered anonymously with a 200.
  • Upgrading to 0.2.0: a response schema now filters the body rather than only checking it, and the radix tree exported as Router is now RadixRouter.
  • Upgrading to 0.3.0: /_oven/* is excluded from the generated OpenAPI document.
  • Upgrading to 0.6.0: every package now requires Bun 1.4 or newer. Nothing else changed for existing code — the whole suite passed unchanged on the new runtime — but an older Bun will refuse to install.

Contributing

git clone https://github.com/hiteshchoudhary/theoven.git
cd theoven && bun install

bun test              # every package
bun run lint
bun run typecheck
bun run check:docs    # every code sample in the docs and in every README

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

CLAUDE.md records the architecture and every locked decision with its rationale; TODO.md tracks what is done and what is next.

License

MIT

About

A modern bun framework that is easy and AI first

Resources

Stars

74 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages