Oriel
Oriel is a Laravel-style, full-stack TypeScript framework for Node and Bun. Routing, models, queues, mail, validation and auth arrive together, designed as one typed toolkit, so you can build the whole app and not just the API.
Everything you reach for in Laravel has a home here, with types all the way down: route names, validated input, model attributes and the props you hand to your pages.
Route.get('/', () => inertia('Welcome'))
Route.resource('posts', PostController)
Route.middleware(['auth']).group(() => {
Route.get('/dashboard', [DashboardController, 'index'])
})export class PostController extends Controller {
async store() {
const data = await StorePostRequest.validate()
const post = await Post.create(data)
return redirect().route('posts.show', post)
}
}Why Oriel?
Node has fast servers and good ORMs, but you still wire a dozen libraries together before you ship a login page. Laravel showed a better way: one framework where every piece already knows the others.
What comes in the box?
HTTP and routing, a console, an ORM, validation, auth and sessions, queues, mail and notifications, cache, events, files, logs and views. Each part is its own package, and they all share one container, one config and one set of contracts.
Routing and controllers
Named routes, groups, middleware and model binding. Every route name is typed, so a typo in a link fails the build, not the user.
export class PostController extends Controller {
async store() {
const data = await StorePostRequest.validate()
const post = await Post.create(data)
return redirect().route('posts.show', post)
}
}Models and migrations
An Eloquent-style ORM on Postgres, MySQL and SQLite, with relations, scopes, eager loading, factories and seeders.
export class Post extends Model {
protected override fillable = ['title', 'body']
author() {
return this.belongsTo(User)
}
}
const posts = await Post.with('author').paginate(15)Queues and mail
Push slow work onto Redis or your database. Jobs, batches, retries and a scheduler, with mail and notifications that queue themselves.
export class SendInvoice extends Queueable {
constructor(public order: Order) {
super()
}
async handle() {
await Mail.to(this.order.email).send(new Invoice(this.order))
}
}
SendInvoice.dispatch(order).onQueue('billing')And more
Validation
Laravel's rule strings and form requests that return typed, validated data.
Auth and sessions
Guards, sessions, hashing, encrypted cookies and API tokens, ready from the start.
Cache and events
Memory, file, database and Redis stores with atomic locks, and queued listeners.
Inertia and Live
Pages in React, Vue, Svelte, Solid or Angular, or server-driven Live components.
A real console
Generators, migrations, workers and your own commands, all behind one oriel CLI.
Files and logs
Local and cloud disks behind one API, and channels for every kind of log.
Three commands to a running app
Pick a starter kit, and you get auth, a database, queues and your frontend wired together from the first command.