Provider Architecture
Every infrastructure piece — caching, events, validation, logging — implements a swappable provider interface. No vendor lock-in.
A lightweight, high-performance TypeScript backend framework for Bun. Provider-based architecture, explicit DI, and a fluent API that makes the right way the easy way.
bun add @orijs/orijs import { Ori, Type, Params } from '@orijs/orijs'
import type { OriController, RouteBuilder } from '@orijs/orijs'
class UsersController implements OriController {
constructor(private users: UserService) {}
configure(r: RouteBuilder) {
r.get('/', () => this.users.findAll())
.get('/:id', (ctx) => this.users.findById(ctx.params.id), {
params: Params.uuid('id')
})
}
}
Ori.create()
.provider(UserService)
.controller('/users', UsersController, [UserService])
.listen(3000)NestJS gets architecture right but is heavy — decorators, reflect-metadata, complex modules. Bun changes the equation with native speed. And frameworks shouldn't lock you into their infrastructure choices. OriJs exists because we wanted all three solved at once.
Fluent builder API replaces @Controller, @Get, @UseGuards. Your controllers are just classes — no framework magic needed for testing.
Every component implements a provider interface. Use Redis today, DynamoDB tomorrow. Your business logic never changes.
Dependencies are visible arrays, not metadata reflection. TypeScript catches mismatches at compile time, not runtime.
Every infrastructure piece — caching, events, validation, logging — implements a swappable provider interface. No vendor lock-in.
Fluent builder API instead of decorators. No reflect-metadata overhead, no hidden control flow, simpler testing.
Native Bun HTTP server, native TypeScript, built-in SQL drivers. Designed for Bun from the ground up.
Dependency injection with explicit arrays. TypeScript catches mismatches, dependencies are visible, tree-shaking works.
Type-safe events with correlation tracking. Saga-pattern workflows with rollback. BullMQ for production, in-process for dev.
Request pipeline with guards for auth, interceptors for cross-cutting concerns, and pipes for input transformation.
No @Module system. No reflect-metadata.
Just a fluent builder that wires providers, controllers, and
services into a linear, visible application lifecycle.
// Every infrastructure piece is a swappable provider
import { Ori } from '@orijs/orijs'
import { BullMQProvider } from '@orijs/bullmq'
import { RedisCacheProvider } from '@orijs/cache-redis'
Ori.create()
// Swap BullMQ for Kafka, RabbitMQ, or SQS
.events(new BullMQProvider(redisOpts))
// Swap Redis for Memcached, DynamoDB, or in-memory
.cache(new RedisCacheProvider(redisOpts))
// Explicit DI — no decorators, no magic
.provider(OrderService, [OrderRepo, EventEmitter])
.controller('/orders', OrdersController, [OrderService])
.listen(3000)One install. TypeScript. Bun. Ship it.
bun add @orijs/orijs