tirne
v0.1.16
Published
Minimal and structured web framework for Bun. Go-inspired, function-first.
Maintainers
Readme
Tirne
Tirne — Write high-performance APIs in one file. Built for Bun. Type-safe by design. Cold starts under 1ms.
📚 Tirne Documentation
Explore the full guide to Tirne — a Bun & Edge-native web framework built for speed, structure, and zero boilerplate.
⚡ Sub-millisecond APIs. First-class control of side effects. 👉 Star Tirne on GitHub
Tirne is a declarative, type-safe framework for Bun — designed to make side effects explicit and performance predictable.
🚀 Quickstart
npx create-tirne-app- Bun
- Cloudflare Workers
This command sets up a ready-to-run Tirne project in seconds.
📣 Love minimal tools that get out of your way? Star the main Tirne repo: https://github.com/Tirne-ts/Tirne
📁 What You Get
A zero-boilerplate project, tailored for your runtime:
index.tswith a working router and a/endpoint- Runtime config files (
bunfig.toml,wrangler.toml) package.jsonwith minimal scripts and dependencies
Example output:
✔ Choose your target environment: › Bun
✔ Project folder: › my-tirne-app
✅ Tirne app created in 'my-tirne-app'
Next steps:
cd my-tirne-app
bun install # or npm install
npm run dev (Bun) # or wrangler dev 🔧 Philosophy
Tirne is built on 5 core principles: E
- Structure as code — Routes, middleware, and logic are configuration, not behavior. Code is a manifest, not a script.
- Errors are values — TirneErrors carry type, status, and intent. They are thrown, but not hidden.
- Composition over convention — Middleware is composed explicitly, and order is part of the contract.
- Types shape behavior — The structure and safety of your API are defined by its types, not docs.
- Designed for the edge — Built for Bun, optimized for fetch, born in the millisecond age.
✨ Features
✨ Features
- ✅ Structure-first routing — Define your entire API as a single declarative structure
- ✅ Composable middleware — Explicit
compose()flow, no decorators or global scope - ✅ Structured errors — Throw
TirneErrorwith type, status, and visibility - ✅ Built-in response helpers —
json(),html(),text(),error()etc... — clean and consistent - ✅ Edge-native execution — Instant cold start & sub-ms response on Bun, Workers, and Deno
- ✅ No boilerplate — No CLI, no config, no directory rules. Just pure code.
- ✅ Type-safe by design — Routes, handlers, errors, all shaped by TypeScript
⚡️ Performance Benchmarks
All tests were performed using Bun v1.1.0 on an M2 Pro chip (macOS), simulating edge runtime conditions.
| Metric | Result | Interpretation |
|--------------------|--------------------|----------------|
| ❄️ Cold Start | 0.02 ms | 🧊 Essentially unmeasurable — perfect for edge/fetch-based runtimes |
| ⚡️ First Request | 0.79 ms | 🚀 Beats the 1ms barrier. Ideal for latency-critical APIs |
| 🔁 Requests/sec | 90,489 rps | 🔥 Comparable to Hono, surpasses Express by 10x+ |
| 📉 Avg Latency | 0.96 ms | ⚡ Sub-millisecond under load — suitable for interactive apps |
| 📦 Throughput | 10.9 MB/sec | 📈 Handles large JSON payloads with ease |
| 🎯 Total Requests | 905,000 in 10s | 💪 Battle-tested for real-world load |
✨ Tirne was designed for edge-first, zero-warmup environments — and these numbers prove it.
🧱 Example with Cookie
import { Server,json,setCookie,requireAuth } from "tirne";
import type { Route } from "tirne";
const routes: Route[] = [
{
method: "GET",
path: "/login",
handler: () => {
const headers = new Headers();
headers.append("Set-Cookie", setCookie("auth", "valid-token", {
httpOnly: true,
path: "/",
maxAge: 3600,
}));
return json({ message: "Logged in" }, 200, headers);
},
middleware: [],
},
{
method: "GET",
path: "/private",
handler: () => json({ message: "Secret data only for authenticated users" }),
middleware: [requireAuth],
},
];
const server = new Server(routes);
export default {
fetch: (req: Request) => server.fetch(req),
};
🔥 Tirne Philosophy – The 5 Laws of Structured Simplicity
A backend should be transparent, fast, and designed like architecture — not like magic. Tirne is built on five modern principles:
Structure is the source of truth
APIs are defined as code, not behavior. No decorators, no conventions — just configuration you can read.Errors are data, not chaos
Exceptions carry type, status, and visibility. You don’t catch them — you design them.Composition is everything
Middleware is composed explicitly. No global state, no stack traces from hell.Built for the edge, shaped by types
Tirne runs instantly on Bun, Workers, and Deno. And your types shape what runs — not your docs.No bootstraps, no boilerplate, no BS
One file. No CLI. No hidden magic. What you write is what you deploy.
🔍 Tirne vs Hono vs Elysia — Key Differences
🔍 Tirne vs Hono vs Elysia — Revisited for 2025
| Axis | Tirne ✨ | Hono 🌿 | Elysia 🧠 |
|-----------------|--------------------------------------------------|--------------------------------------------------|----------------------------------------------|
| Philosophy | Structure and Side Effect Control | Simplicity and Familiarity | Type-maximalism and Decorator DSL |
| Routing | Declarative Route[] structure | Chain-style app.get("/foo") | Macro-enhanced handler declarations |
| Middleware | Explicit compose([...]), scoped per route | Global app.use() and nested routers | Plugin + lifecycle hooks + decorators |
| Error Model | TirneError: structured error with metadata | throw or return c.text() | set.status() with plugin-driven handling |
| Type Safety | Type-driven config and handlers (Route<T>) | Medium (context-specific typing) | Extremely strong, but tightly coupled to tools |
| Response API| json(), error() as pure return values | c.json(), c.text() methods | set.response() side-effectful injections |
| Extensibility| Middleware and composition primitives | Plugins with shared context | Plugins + Macros + Decorators |
| Dependencies| 🟢 Zero external runtime deps | 🟡 Lightweight | 🔴 Heavy: valibot, macros, SWC, etc. |
| Runtime Support | ✅ Bun / Workers | ✅ Bun / Node / Workers/ Deno | ❌ Bun-only, limited to SWC macro pipelines |
| Ideal Users | API designers, type-aware minimalists, edge devs| Express/Deno users wanting familiar DX | TS power users who love macros & decorators |
Tirne is not just minimal — it's architectural. It gives you full control over structure, type, and execution without opinionated tooling or hidden behaviors.
📦 Install
bun add tirneTo use in Workers :
npm install tirne🤍 Use Cases
Tirne is ideal for:
⚡️ Need edge-speed APIs — Sub-millisecond response times on Bun, Workers, and Deno.
📦 Want type-driven reliability — APIs shaped by types, not runtime guesswork.
🌐 Deploy on modern runtimes — Runs fetch-first, works anywhere: Bun, Node, Workers, Deno.
🧪 Design with side effects in mind — Control cookies, headers, and auth with intention.
💥 Ready to Write Real Code Again?
🚀 If you’re tired of magic, macros, and monoliths — try Tirne.
👉 ⭐️ Star on GitHub to join the movement.
📜 License
Apache 2.0
