Guren at a Glance
The fullstack TypeScript framework that feels like Laravel — powered by Bun.
Documentation
Guides for every subsystem — routing, models, auth, queues — and tutorials that build a working app. Every page starts with code you can run.
The fullstack TypeScript framework that feels like Laravel — powered by Bun.
An honest look at where Guren fits — compared with Hono, Next.js, AdonisJS, and Laravel — and why it is built the way it is.
This guide has two parts. Part A gets a fresh Guren app running in about five minutes with SQLite — no Docker, no database server. Part B covers the full setup: Postgres or MySQL, environment variables, feature generators, and production builds. Start with Part A; come back to Part B when you need it.
This tour follows a single request — GET /posts — through every layer of a Guren app: route, controller, validation, model, resource, Inertia page, and test. Read it to build a mental map; each stop links to the guide that goes deeper.
Guren reimagines Laravel's design principles in TypeScript, tying together Bun, Hono, Inertia.js, React, and Drizzle ORM into a full-stack MVC framework. This document outlines the end-to-end flow from routing to response generation and explains the main building blocks.
Routes map URLs to your application logic. They define what happens when a user visits /posts, submits a form, or hits an API endpoint. In vNext-style apps, each application owns a Router instance and route files export a registrar function instead of mutating a global registry.
Controllers are where your application logic lives. They receive HTTP requests, interact with models and services, and return responses. Think of them as the glue between what the user asks for and what your app delivers.
Guren routes and applications share Hono's middleware model but expose Laravel-style ergonomics for common tasks. You can register middleware globally on the Application instance, per-route via the routing DSL, or through named aliases and groups.
Cross-Site Request Forgery (CSRF) protection prevents malicious websites from submitting forms on behalf of authenticated users. Guren provides built-in CSRF middleware that integrates seamlessly with sessions.
Guren's primary validation path is schema-first. Use Zod-compatible schemas in controllers, route definitions, or middleware so request parsing and type inference stay in one place. A legacy FormRequest compatibility layer still exists for migrations.
Guren provides multiple layers of error handling, from a centralized ExceptionHandler to controller-level exception catching. Built on Hono's robust error handling primitives, you can customize how errors are displayed to users in both development and production.
Guren uses Drizzle ORM and supports PostgreSQL, SQLite, MySQL, and Aurora Serverless (AWS Data API). You define your schema in TypeScript, derive models from those tables, and get a fluent query API that feels like Laravel Eloquent while staying fully type-safe.
Guren delivers a single-page application experience by combining Inertia.js with React. Controllers return Inertia responses, and the frontend renders the matching React components located under resources/js/pages/.
this.view() renders a JSX component to a plain server-rendered HTML response — the non-hydrating counterpart to this.inertia() for public, read-mostly pages: blog posts, docs, marketing pages. No client framework, no hydration, no Inertia page-payload script in the document. It is what guren.dev uses for its own blog posts.
Guren ships with a Laravel-inspired authentication stack that sits on top of the session middleware and the ORM layer. The goal is to match the expressiveness of Laravel's guards and user providers while staying idiomatic to TypeScript and Bun.
Guren ships an OAuth 2.0 authorization-code flow for "Sign in with GitHub / Google / Discord" style login. It handles the redirect, CSRF-safe state, token exchange, and profile fetch — you wire it into your own login controller and session.
Authorization determines what an authenticated user is allowed to do. Guren provides a policy-based authorization system inspired by Laravel.
Guren provides a secure API token system for authenticating API requests. Tokens are hashed before storage, support abilities (scopes), and can have expiration times.
Guren provides a secure password reset system with token generation, verification, and expiration. The token is signed rather than stored: only an opaque token id reaches the store.
Guren provides a secure email verification system with token generation, verification, and expiration. The token is signed rather than stored: only an opaque token id reaches the store.
Guren provides utilities for encrypting data and hashing passwords securely.
Guren provides a simple yet powerful event system for decoupling components in your application. Events allow you to broadcast occurrences in your application that other parts can listen and react to.
Guren provides a robust queue system for deferring time-consuming tasks to be processed in the background. This is essential for maintaining fast response times while handling operations like sending emails, processing uploads, or making external API calls.
Guren provides a unified caching API with support for multiple storage backends. Caching helps improve application performance by storing expensive computations or database queries for quick retrieval.
Guren provides a fluent API for sending emails with support for multiple transport backends. The mail system integrates with the queue system for async sending and supports HTML templates, attachments, and more.
Guren provides a unified API for sending notifications across multiple channels like email, database, Slack, and more. Notifications are class-based, making them reusable and easy to test.
Guren provides a broadcasting system for real-time event broadcasting to connected clients. This is useful for building features like live notifications, chat applications, and real-time dashboards.
Guren provides a unified file storage API with support for multiple storage backends. The storage system makes it easy to work with local filesystems, Amazon S3, and other cloud storage providers with a consistent interface.
Attachments connect uploaded files to your models: a Post has a cover
Guren provides a fluent API for defining scheduled tasks within your application. Instead of managing multiple cron entries, you can define your entire task schedule in code.
Console commands let you run application code from a terminal — backfills, one-off maintenance, reports — with the same models, services, and container your HTTP handlers use.
Guren provides a flexible rate limiting system to protect your application from abuse. It supports multiple storage backends, custom key generators, and both fixed and sliding window algorithms.
Guren provides a flexible logging system with multiple channels, log levels following RFC 5424, and contextual logging support.
Guren provides a comprehensive health checking system to monitor your application's dependencies and services. Use health checks to expose a /health endpoint for load balancers, orchestrators, and monitoring tools.
Guren ships internationalization end to end: file-based translation catalogs, per-request locale detection, translation helpers in controllers and React pages, pluralization rules for 15+ languages, typed translation keys, and a consistency checker for your catalogs.
API Resources provide a transformation layer between your models and API responses. They give you fine-grained control over how data is serialized to JSON.
@guren/plugin-markdown renders markdown to HTML with hardened defaults: GitHub Flavored Markdown, sanitized output safe for dangerouslySetInnerHTML, GitHub-style alerts, heading anchors, and optional shiki code highlighting. It is the pipeline guren.dev itself uses for its docs and blog.
A single well-written test catches bugs before your users do. Guren makes testing so convenient that writing tests feels faster than manually checking things in a browser.
This guide summarizes the steps required to promote a freshly scaffolded Guren application to production. It assumes you generated your project with create-guren-app and that you have a PostgreSQL instance available.
Guren runs on AWS Lambda's Node.js runtime. The official @guren/plugin-lambda plugin handles bundling, and a CDK construct provisions the full stack — HTTP, queues, scheduled tasks, CLI commands, and static assets.
Guren runs on Cloudflare Workers via @guren/plugin-cloudflare, with D1 as the database. This guide covers the full path from an empty account to a deployed app.
This runbook defines minimum reliability operations before GA.
AI agents write code faster than anyone can keep documentation honest by
AI agents call applications over MCP. Guren does not ask you to write a second
A durable agent is a long-lived, stateful process your own application hosts, and it reaches that application only through the agent tools the routes already declare.
This guide walks you through building an application with user registration, login, and protected routes. You will go from an empty directory to a working auth flow in under ten minutes.
This guide walks you through building and shipping a JSON API with Guren. You will scaffold an API-only project, define a database schema, create controllers with validation, and test your endpoints.
This guide covers the essential steps to take a Guren application from local development to a production environment. It focuses on Docker-based deployment with Bun.
This guide covers the most common issues you will encounter when developing with Guren and how to fix them quickly. When something goes wrong, start here before diving into individual package documentation.
Guren ships with two companion CLIs:
This guide walks you through creating, testing, and publishing a Guren plugin.
| Runtime | Versions | Status |
Use this guide for minor-to-minor upgrades.
This document defines the minimum release contract for production use.
Short definitions for common terms in the Guren docs.
In this chapter you scaffold a Guren app, read what the scaffold gave you, make one change by hand with a test in front of it, hand one change to a coding agent and watch the harness check its work, and finish with a container image you can run anywhere. Every later chapter ends the same way: gate green, committed, shippable.
Chapter 1 gave you an app with one page you did not write. This chapter has you write the next one from blank files, in the order the rest of the course uses: a failing test, a route, a controller, a page. Then you specify a second page with a test and hand it to the agent, and you watch the harness load the right rule for the file it is editing.
A blog needs posts, and posts need somewhere to live. In this chapter you define the first table, generate and run its migration, write the model that reads it, and build the two pages that show posts. Then you specify the create form with a test and hand it to the agent, and you see the scaffold skill steer it toward the generators instead of typing.
Chapter 3 put a schema inside the controller and sent raw field maps to the pages. This chapter gives both a proper home: a validator file that the route, the controller and the form all share, with messages a person would write; and a resource class that decides what a post looks like to the browser. Then you specify editing, deleting and pagination with tests, hand them to the agent, and use the code-review subagent as a second reader before you accept.
Everything so far has been anonymous. This chapter gives the blog users: a table with a password hash, a model that knows how to hash, sessions and the CSRF protection that comes with them, and registration, login and logout built by hand. Then you specify a profile page with a test and hand it to the agent, and you see what guren context User gives an agent before it touches a model.
The blog has users now, but nothing checks for one: a guest can still write, edit and delete posts, and guren audit has been saying so since chapter 3. This chapter puts the post mutations behind a login wall, gives every post an author with a migration that keeps the rows you already have, and then hands the agent a migration of its own and watches the db-manage skill keep it safe. It ends by showing you what bunx guren add auth would have written, now that you can read it.
Chapter 6 built a wall: you have to be signed in to change a post. It did not build a door: any signed-in user can edit or delete anyone's post. The difference is authentication (who are you?) against authorization (are you allowed?), and this chapter builds the second by hand with a policy. Then it does something no other chapter does on purpose: it hands the agent a feature without mentioning authorization, and shows you which of your safeguards notices when it is missing.
Chapter 6 left you with authorsOf, a helper that collects author ids and runs one IN query. It works, and it is what a relationship does under the hood. This chapter replaces it with the real thing: belongsTo and hasMany declared once on the models, loaded with with(). Then it adds comments, the first table that points at two others, and hands the agent the one shape you have not built yet: a many-to-many, tags, through a pivot table.
A blog wants pictures. This chapter installs Guren's attachments layer, gives every post a cover image that is stored outside the public directory and served through a signed URL, and then hands the agent a gallery. Along the way guren check gets a new set of things to be right about, and you see it catch the one mistake that turns "private" into "public".
Everything so far finished inside the request: validate, write a row, redirect. This chapter is about the work that should not. When Bob comments on Ada's post, Ada gets an email, and Bob's browser must not wait for a mail server to answer before it sees the page.
Eleven chapters of building a blog for people. This chapter opens the same app to a different kind of caller: an agent that reads your posts and publishes a draft, through the routes you already wrote.
Every project you have ever joined had a README that was wrong. Not maliciously: someone wrote it when it was true, the code moved, and nothing failed. That is the whole problem, and it has exactly two halves.