<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Daiki Urata</title>
    <description>The latest articles on DEV Community by Daiki Urata (@7nohe).</description>
    <link>https://dev.to/7nohe</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4084940%2Fa2694bf0-3bd4-4180-8ec2-6f46307dd8ba.png</url>
      <title>DEV Community: Daiki Urata</title>
      <link>https://dev.to/7nohe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/7nohe"/>
    <language>en</language>
    <item>
      <title>I'm building Guren, a fullstack TypeScript framework for the AI-agent era</title>
      <dc:creator>Daiki Urata</dc:creator>
      <pubDate>Wed, 19 Aug 2026 12:22:30 +0000</pubDate>
      <link>https://dev.to/7nohe/im-building-guren-a-fullstack-typescript-framework-for-the-ai-agent-era-47k6</link>
      <guid>https://dev.to/7nohe/im-building-guren-a-fullstack-typescript-framework-for-the-ai-agent-era-47k6</guid>
      <description>&lt;p&gt;&lt;a href="https://guren.dev" rel="noopener noreferrer"&gt;Guren&lt;/a&gt; is a fullstack TypeScript framework for Bun. I started it because I wanted Laravel's shape in TypeScript, and I kept going for a different reason: once I was handing most of the code to agents, what I wanted from a framework was a way to check what came back.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/gurenjs" rel="noopener noreferrer"&gt;
        gurenjs
      &lt;/a&gt; / &lt;a href="https://github.com/gurenjs/guren" rel="noopener noreferrer"&gt;
        guren
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Guren is a Bun-native TypeScript MVC framework that unites Laravel-like ergonomics with Hono, Inertia.js, React, and Drizzle ORM, aiming to deliver a fast, elegant full-stack workflow that keeps frontend and backend work in sync.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Guren&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://x.com/gurenjs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7c9befc51eb8e2d5190b6036697fdcfb334005de6837e5affd20e38dd34a8feb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f666f6c6c6f772d253430677572656e6a732d626c61636b3f6c6f676f3d78" alt="X (Twitter)"&gt;&lt;/a&gt;
&lt;a href="https://github.com/gurenjs/guren/discussions" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/62a4474e6a73baecea7791d6143a58f79f6760106e864f144e9e5b89859531bd/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f64697363757373696f6e732f677572656e6a732f677572656e" alt="GitHub Discussions"&gt;&lt;/a&gt;
&lt;a href="https://github.com/gurenjs/guren/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a href="https://github.com/sponsors/7nohe" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2b4a42a2163b63add83eebd701834de0aadf204647ef113156726774cc0a2a0a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73706f6e736f72732f376e6f68653f6c6f676f3d67697468756273706f6e736f7273" alt="GitHub Sponsors"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The fullstack TypeScript framework for the AI-agent era.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Laravel-style conventions, end-to-end type safety, and built-in agent introspection and verification — routing, controllers, ORM, authentication, and Inertia.js + React in one cohesive experience that humans and AI coding agents navigate from the same map.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;v2&lt;/strong&gt; — Stable. Breaking changes only in major releases, per the &lt;a href="https://github.com/gurenjs/guren/docs/en/guides/release-policy.md" rel="noopener noreferrer"&gt;release policy&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 1. Scaffold a new app with authentication (dependencies install automatically)&lt;/span&gt;
bunx create-guren-app my-app --auth
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; my-app

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 2. Run migrations and seed the demo user (SQLite by default — no server needed)&lt;/span&gt;
bun run db:migrate
bun run db:seed

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; 3. Start the dev server&lt;/span&gt;
bun run dev&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Open &lt;code&gt;http://localhost:3333&lt;/code&gt; and sign in at &lt;code&gt;/login&lt;/code&gt; with &lt;code&gt;demo@example.com&lt;/code&gt; / &lt;code&gt;secret&lt;/code&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Add features as you go&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;bunx guren add auth            &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Authentication&lt;/span&gt;
bunx guren add resource posts --fields &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;title:string,body:text&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;  &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; CRUD resource&lt;/span&gt;
bunx guren add queue           &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Background jobs&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/gurenjs/guren" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;I like the way Laravel and Rails let you build. A feature is a route, a controller, a model and a view, and authentication, queues, mail and validation are already wired together before you start.&lt;/p&gt;

&lt;p&gt;TypeScript has the parts. Hono for HTTP, Drizzle for the ORM, Zod for validation, Inertia and React for rendering, all of them good. What's missing is an agreed way to connect them, so every project ends up wiring it slightly differently, and I've written that wiring more times than I want to count.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mistakes moved
&lt;/h2&gt;

&lt;p&gt;I hand most of that to coding agents now. Models got good enough that obviously broken output mostly stopped showing up, and what replaced it is harder to deal with: code that reads fine and is subtly wrong, arriving faster than I read carefully.&lt;/p&gt;

&lt;p&gt;It gets worse outside the training data. When I published v2.0.0, the new API shapes were younger than any model's training set, and the agents didn't slow down for that at all. They filled the gaps by guessing, and the guesses looked like working code.&lt;/p&gt;

&lt;p&gt;Fullstack TypeScript frameworks are not a new idea and several of the existing&lt;br&gt;
ones are good. What I couldn't find was one that treated agent generation and&lt;br&gt;
mechanical verification as a design input instead of something added on later, so&lt;br&gt;
I started building one.&lt;/p&gt;
&lt;h2&gt;
  
  
  What's in it
&lt;/h2&gt;

&lt;p&gt;Routing, controllers, ORM, authentication, and an Inertia.js + React frontend, as one experience. Nothing underneath is new: HTTP is Hono, the ORM is Drizzle, validation is Zod, rendering is Inertia + React + Vite. Guren doesn't ship its own ORM or its own validator, it gives those defaults a set of conventions.&lt;/p&gt;

&lt;p&gt;A controller looks about how you'd expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@guren/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/.guren/pages.gen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validateParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PostIdParamSchema&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOrFail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;// throws a 404 on its own&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inertia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Show&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;store&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validateBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CreatePostSchema&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;// 422 on failure&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;userOrFail&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                &lt;span class="c1"&gt;// 401 if anonymous&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;authorId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Batteries are included in the Laravel sense: authentication with OAuth providers, queues and jobs, mail, events and listeners, cache, notifications, broadcasting, scheduling, storage, i18n, policies, console commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types that cross the boundary
&lt;/h2&gt;

&lt;p&gt;You bind a Zod schema to a route:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts.store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PostPayloadSchema&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;PostController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the form on the other side derives its type from that schema instead of restating it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PostFormData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;RouteBody&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ApiRoutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts.store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useForm&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PostFormData&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a field to the schema on the server and the form's type follows. Rename the route and &lt;code&gt;route('posts.store')&lt;/code&gt; stops compiling. Page props work the same way, checked against the page component's own &lt;code&gt;Props&lt;/code&gt; interface, so a misspelled prop is a typecheck failure rather than a blank space on the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Letting the project explain itself
&lt;/h2&gt;

&lt;p&gt;Early on I ran an evaluation to see what a feature actually costs an agent on each framework. I expected Guren to come out cheap, because a framework that has already decided things for you should mean less code for the agent to write. The first bare measurement put it at a $5.54 median, 2.7 times Hono's.&lt;/p&gt;

&lt;p&gt;The stream analysis explained it. Agents were spending 17 to 46 percent of all their tool actions reverse engineering &lt;code&gt;@guren/*&lt;/code&gt; APIs out of &lt;code&gt;node_modules&lt;/code&gt; dist bundles, reading minified output to find out what a method is called. The&lt;br&gt;
implementation work itself was fine. What cost money was discovery, which makes sense in retrospect, since the model knows Hono and Next.js from training data and has never seen Guren. So I fixed the documentation and measured again, which brought it to $3.35.&lt;/p&gt;

&lt;p&gt;That's the problem &lt;code&gt;guren context&lt;/code&gt; exists to solve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Post&lt;/span&gt;

&lt;span class="gu"&gt;## Model — app/Models/Post.ts (table: `posts`)&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Columns: id, title, excerpt, body, authorId
&lt;span class="p"&gt;-&lt;/span&gt; belongsTo: &lt;span class="sb"&gt;`author`&lt;/span&gt; → PostAuthorSummary

&lt;span class="gu"&gt;## Referenced by&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; User — hasMany &lt;span class="sb"&gt;`posts`&lt;/span&gt;

&lt;span class="gu"&gt;## Routes (8)&lt;/span&gt;
| Method | Path | Name | Action | Body |
|--------|------|------|--------|------|
| GET | /posts | posts.index | PostController.index | |
| GET | /posts/:id | posts.show | PostController.show | |
| POST | /posts | posts.store | PostController.store | { title: string; excerpt: string; body: string } |

&lt;span class="gu"&gt;## Pages (4)&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; posts/Show — Props: &lt;span class="sb"&gt;`{ post: PostResourceData }`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; posts/Edit — Props: &lt;span class="sb"&gt;`{ post: PostFormValues | null postId: number ... }`&lt;/span&gt;

&lt;span class="gu"&gt;## Resource — app/Http/Resources/PostResource.ts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One command, and &lt;code&gt;--json&lt;/code&gt; gives the machine-readable version. After the agent writes something, there are commands that check it: &lt;code&gt;guren check&lt;/code&gt; verifies that routes, controllers and pages still agree and that route files are actually wired into a registrar, &lt;code&gt;guren audit&lt;/code&gt; flags mutating routes with no validation or auth along with raw SQL and secrets, and &lt;code&gt;guren spec:generate&lt;/code&gt; regenerates the ER diagram, domain model and screen inventory from code so CI fails when they drift.&lt;br&gt;
None of it depends on trusting the agent, since the checks run against the repository either way.&lt;/p&gt;
&lt;h2&gt;
  
  
  What the numbers say
&lt;/h2&gt;

&lt;p&gt;I publish the evaluation rather than describing it: the same feature task, on several frameworks, scored automatically by typecheck, the full test suite, and a hidden HTTP smoke the agent never sees.&lt;/p&gt;

&lt;p&gt;On the frameworks the model already knows well, every trial shipped, and Guren still sits at a $3.35 median against Hono's $2.03.&lt;/p&gt;

&lt;p&gt;The result I care about is from the day I published v2.0.0, when the breaking API changes were younger than any model's training data. With the guidance every new project scaffolds, agents passed 3 of 3 at a $4.90 median. With that guidance stripped out, 1 of 3 at $6.94. The failures guessed at API shapes v2 had changed, the paginated response structure and the testing assertions, and then wrote tests around the wrong guesses.&lt;/p&gt;

&lt;p&gt;Three trials per arm isn't a statistical claim.&lt;/p&gt;

&lt;p&gt;Every round is published, including one where a harness change I was confident about turned out to have quietly lost an earlier win. There's also a correction I had to make this month: an outside review found that the guidance an agent reads wasn't being counted in any of the metrics, sitting right under the section arguing Guren is cheap to read. It's 1,784 lines and 22,582 tokens, and it has its own row now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://guren.dev/blog/agents-on-guren-the-first-benchmark-report" rel="noopener noreferrer"&gt;The benchmark report&lt;/a&gt; has the detail, and &lt;a href="https://github.com/gurenjs/framework-comparison/tree/main/agent-eval" rel="noopener noreferrer"&gt;the raw rounds are here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Running it
&lt;/h2&gt;

&lt;p&gt;Development assumes Bun's toolchain, though deployment doesn't: your own Bun server, or the first-party plugins for AWS Lambda, Vercel and Cloudflare Workers.&lt;br&gt;
guren.dev is a Guren app, blog and admin screen included, running on Workers and D1. Building it turned up a handful of framework bugs, which is roughly why I built it there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bunx create-guren-app my-app &lt;span class="nt"&gt;--auth&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;my-app
bun run db:migrate &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; bun run db:seed
bun run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SQLite is the default, so there's no database server to set up. Open &lt;code&gt;http://localhost:3333/login&lt;/code&gt;, sign in with &lt;code&gt;demo@example.com&lt;/code&gt; / &lt;code&gt;secret&lt;/code&gt;, and you have an authenticated app running.&lt;/p&gt;

&lt;h2&gt;
  
  
  When not to use it
&lt;/h2&gt;

&lt;p&gt;If your product is rendering-centric RSC-style React, Next.js is a better fit and I'd reach for it too. Plain Hono is lighter for anything that isn't really an MVC app, a webhook receiver being the obvious case, and if Bun is off the table on your developers' machines then none of this helps you. The docs have &lt;a href="https://guren.dev/docs/guides/why-guren" rel="noopener noreferrer"&gt;a longer version of this&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The community is small. Mostly me, so far.&lt;/p&gt;

&lt;p&gt;If you like how Laravel or Rails feel and you're tired of rebuilding the same wiring in TypeScript, it shouldn't cost much to try.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/gurenjs/guren" rel="noopener noreferrer"&gt;https://github.com/gurenjs/guren&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://guren.dev/docs" rel="noopener noreferrer"&gt;https://guren.dev/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Feedback: GitHub Discussions&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
      <category>ai</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
