Skip to main content
Deno 2 is finally here πŸŽ‰οΈ
Learn more

Tirne

Cloudflare Workers bun version license stars

Tirne β€” from Old English β€œstructure, strength” β€”γ€€structure over boilerplate. A minimal, type-safe web framework for Multi Runtime, with edge-native performance and first-class control of side effects.”


Docs

πŸ“š Tirne Documentation

Explore the full guide to Tirne β€” a Bun & Edge-native web framework built for speed, structure, and zero boilerplate.

πŸ‘‰ https://tirne.dev


⚑ 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

Tirne setup terminal screenshot

Choose your environment:
  • 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.ts with a working router and a / endpoint
  • Runtime config files (bunfig.toml, wrangler.toml)
  • package.json with 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

  1. Structure as code β€” Routes, middleware, and logic are configuration, not behavior. Code is a manifest, not a script.
  2. Errors are values β€” TirneErrors carry type, status, and intent. They are thrown, but not hidden.
  3. Composition over convention β€” Middleware is composed explicitly, and order is part of the contract.
  4. Types shape behavior β€” The structure and safety of your API are defined by its types, not docs.
  5. 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 TirneError with 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.



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:

  1. Structure is the source of truth
    APIs are defined as code, not behavior. No decorators, no conventions β€” just configuration you can read.

  2. Errors are data, not chaos
    Exceptions carry type, status, and visibility. You don’t catch them β€” you design them.

  3. Composition is everything
    Middleware is composed explicitly. No global state, no stack traces from hell.

  4. Built for the edge, shaped by types
    Tirne runs instantly on Bun, Workers, and Deno. And your types shape what runs β€” not your docs.

  5. 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 tirne

To 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.

GitHub Stars


πŸ“œ License

Apache 2.0