Tirne: The Explicit, Go-Inspired Web Framework for Bun, Node,Deno and Workers
"Minimal" Frameworks Are Lying to You Let’s cut the crap: Hono and Elysia aren’t scalable web frameworks. They’re great for toy projects, fast demos, and Hacker News points — but if you've ever tried to scale them in a production-grade app, you already know the pain: Middleware logic hidden in plugins Global state chaos Decorators breaking in silence Implicit routing behavior you can’t trace They look clean on day one. By day thirty, it’s unmaintainable abstraction soup. Tirne: Functional, Explicit, Built to Scale Tirne is a Bun-native web framework designed by engineers who got burned by magic-driven toolchains. We didn’t want to build a framework. We wanted to stop debugging decorators at 2am. Tirne takes inspiration from Go’s net/http — where functions are first-class, structure is visible, and control is always yours. // index.ts import { createRouter, compose, json } from "tirne"; const logger = async (ctx, next) => { console.log(`[${ctx.method}] ${ctx.url.pathname}`); return await next(); }; const routes = [ { method: "GET", path: "/", handler: compose([logger], () => json({ hello: "Tirne" })), }, ]; Bun.serve({ fetch: createRouter(routes) }); That’s it. No macros. No CLI. No hidden behavior. It scales because it’s explicit. Why Tirne Exists (and Why You Might Need It) Because you shouldn’t need to read framework internals to understand a handler. Because Go-style error handling is safer than try/catch gymnastics. Because routing and middleware should be functions, not chained spellbooks. Because “zero-boilerplate” should not mean “zero control.” Tirne is what you'd get if Go had a baby with Bun — and it was raised by a backend engineer who hates decorators. The Real Comparison: Tirne vs the Toys Axis Tirne ✨ Hono

"Minimal" Frameworks Are Lying to You
Let’s cut the crap: Hono and Elysia aren’t scalable web frameworks.
They’re great for toy projects, fast demos, and Hacker News points — but if you've ever tried to scale them in a production-grade app, you already know the pain:
- Middleware logic hidden in plugins
- Global state chaos
- Decorators breaking in silence
- Implicit routing behavior you can’t trace
They look clean on day one. By day thirty, it’s unmaintainable abstraction soup.
Tirne: Functional, Explicit, Built to Scale
Tirne is a Bun-native web framework designed by engineers who got burned by magic-driven toolchains.
We didn’t want to build a framework.
We wanted to stop debugging decorators at 2am.
Tirne takes inspiration from Go’s net/http
— where functions are first-class, structure is visible, and control is always yours.
// index.ts
import { createRouter, compose, json } from "tirne";
const logger = async (ctx, next) => {
console.log(`[${ctx.method}] ${ctx.url.pathname}`);
return await next();
};
const routes = [
{
method: "GET",
path: "/",
handler: compose([logger], () => json({ hello: "Tirne" })),
},
];
Bun.serve({ fetch: createRouter(routes) });
That’s it. No macros. No CLI. No hidden behavior. It scales because it’s explicit.
Why Tirne Exists (and Why You Might Need It)
- Because you shouldn’t need to read framework internals to understand a handler.
- Because Go-style error handling is safer than
try/catch
gymnastics. - Because routing and middleware should be functions, not chained spellbooks.
- Because “zero-boilerplate” should not mean “zero control.”
Tirne is what you'd get if Go had a baby with Bun — and it was raised by a backend engineer who hates decorators.