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 two courses that build a working app: one by hand, one by directing a coding agent. 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.
Bun ships a runtime, a package manager, a bundler and a test runner, and its dev server can serve HTML pages next to API routes. It does not ship a fullstack framework, and its own documentation says so. This page is for anyone searching for a Bun fullstack framework: what Bun, Hono and Elysia each cover, what is left for you to assemble, and how Guren fills that gap while still deploying to Node.js, Vercel and Cloudflare Workers.
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.
A Guren app keeps its configuration in config/. Two kinds of file live there:
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 a method and a URL to the code that answers it: a controller action or an inline handler. Each application owns one Router. A route file exports a registrar, a function that receives that router and registers routes on it, and src/app.ts passes the registrar to createApp().
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.
Middleware runs code around a request: before the controller action, after it, or instead of it. Guren uses Hono's middleware model, and you attach middleware in one of three places:
Cross-Site Request Forgery (CSRF) protection prevents malicious websites from submitting forms on behalf of authenticated users. Guren's CSRF middleware issues a token per session (or a double-submit token for guests) and verifies it on POST, PUT, PATCH, and DELETE.
Validate request input against a schema and get typed, parsed values back. When the input is invalid, the request ends with a 422 response, or, on an Inertia request, a redirect back to the form with one error message per field.
An exception thrown anywhere in a request ends up at the ExceptionHandler, which decides what gets reported and what the client sees. You customize it from a service provider, and an ordinary try/catch inside a controller handles the errors you want to recover from on the spot. The handler answers differently in development and in production.
Guren reads and writes the database through models built on Drizzle tables, with a query API shaped like Laravel's Eloquent and typed from your schema. A new app uses SQLite and needs no setup; PostgreSQL, MySQL and Aurora Serverless are a configuration change away.
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/. For the parts of the Inertia protocol the server implements, see Inertia Protocol Support.
Guren ships its own Inertia server adapter inside @guren/core, written against the Inertia protocol as @inertiajs/react 3 speaks it. This page is the coverage table: which parts of the protocol the adapter implements, which it leaves out, and where each part is documented. If you arrive from the Laravel, Rails or AdonisJS adapter, read this page first and the Frontend guide second.
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.
Add sign-in, registration and password reset to an app with one command, then protect routes and read the signed-in user in controllers. The first half of this page covers that generated setup; the second half covers sessions, guards and user providers, for when you change how it works.
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.
The queue moves slow work off the request: sending mail, processing uploads, calling an external API. A controller dispatches a job and responds immediately; a worker process picks the job up and runs it afterwards.
The cache stores the result of slow work, such as a database query or a computation, under a key so the next request can read it back. Add it with bunx guren add cache, pick a backend with CACHESTORE, and read the cache from the container as cache.
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.
A health manager runs the checks you register (database, Redis, cache, storage, process memory, or one you write yourself) and reports healthy, degraded, or unhealthy. Serve that report on 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.
Test your app over HTTP with TestApp: send a request through the real middleware and routes, then assert on the response. This page also covers signing a user in, keeping tests off your development database, and swapping mail, events and queues for fakes.
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
Specifications written as documents get argued about; specifications a customer can click get corrected. Prototype mode lets you build the screens of a feature before any of its backend exists, host them on any static file host with no server behind them, walk a customer through them, and then start the backend from the same code, with the pages you showed becoming the pages you ship.
An implementation plan is a design document for a change, written as JSON before any code exists. Guren checks it against your application, renders it as a page a person can review, stamps it when it is approved, breaks it into steps, and then reads from the code which parts of it exist. The agent that implements the plan never reports its own progress: plan:status and plan:verify derive it from the schema, the route graph, the controllers, the pages and the test results.
This page describes the plan file itself: its sections, element ids and changes, acceptance behaviours, questions and commands. For the workflow that renders, approves and implements it, see Implementation Plans; the words this page uses (element, behaviour, step) are defined in its Terms table.
plan:next sends scaffold and tests steps to plan:scaffold, which writes code and test skeletons from an approved plan. This page describes what it writes, what it leaves for you, and when it refuses. The workflow around it is in Implementation Plans, and element states such as planned and wired are defined in Reading progress.
This page collects the rules behind approval and verification, for when a verdict surprises you. The workflow they belong to is in Implementation Plans; the terms are defined in its Terms table.
AI agents call applications over MCP. Guren does not ask you to write a second
Once routes are served as agent tools (see Agent Interface),
An AI agent is a class in your application that calls a language model and reaches the application only through the agent tools its routes already declare. @guren/plugin-ai builds it on the Vercel AI SDK: the SDK talks to the provider, and the plugin decides which of your routes the model may call, as whom, and what gets recorded.
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.
Apps scaffolded with create-guren-app include an AI agent harness: files that teach coding agents how to work in a Guren app, and hooks that run Guren's checks while they work. This page covers what is installed for each agent, what the hooks do, and how agent:init and agent:sync maintain the files.
bunx guren graph reports how your app is wired: its routes, controllers, models, Inertia pages, middleware, validators, policies and tests, and the evidence that links them. bunx guren runtime:errors lists the server errors the running development app hit recently. Coding agents read the same data over MCP, and the Dev Center shows both in a browser.
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:
The CLI Reference lists check, audit, gate, introspect and doctor. This page holds the rules behind them: what the audit's policy rule looks for, how to suppress an audit finding, what introspect runs, the extra rules for agent routes and in-process agents, architecture boundaries, and which facts the checks read from the registered (but never booted) app.
This guide walks you through creating, testing, and publishing a Guren plugin.
| Runtime | Versions | Status |
Use this guide when you move an app to a newer version. Follow the workflow below. The migration notes are listed by release (the version on the GitHub release), newest first; apply the ones for every release you cross, starting from the oldest.
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.
In this course a coding agent (Claude Code) writes the code, and you decide what gets built. You make a meetup app in which users organize meetups and others register until a meetup is full. It takes two plans. You review each plan before any code exists, approve it, and then watch the agent build it one step at a time.
This chapter scaffolds the app, adds sign-in, and shows you the two parts of the harness that the rest of the course leans on. You write no application code.
A plan is the design of a change, written as JSON before any code exists. In this chapter the agent writes the first one, for organizing meetups, and you read it on the review page Guren renders from it.
Chapter 2 ended with a list: one open question, five missing behaviours. In this chapter you hand that review to the agent, check what it changed, and approve the plan. Approval is the one step in the loop that only you take.
The plan is approved. In this chapter the agent builds it. Guren splits the plan into steps; the agent takes one, implements it, has it verified, and commits. Your part is to read each commit before the next one lands.
Once a plan is built, plan.json goes quiet: nobody edits an approved plan to describe code that exists. What the plan knew (why the feature exists, which rules it must keep, what it deliberately left out) still matters, though. Closing a plan writes that knowledge into documents the next agent reads.
The first plan only added things. Registrations cannot: a meetup has to learn about its registrations, its page has to show the seats left, and code you already accepted has to change. This chapter plans that change and approves it. The review gets harder, because now the question is not only "is this right?" but also "what else does it touch?"
A plan is approved against the app as it was at one commit. Real work does not stop at that commit: a teammate merges a refactor, and a name the plan relies on disappears. This chapter builds the registrations plan, lets that happen halfway through, and shows how Guren stops the agent instead of letting it build on a design that no longer fits.