🚀 Tirne — Zero-Boilerplate APIs with Edge-Native Speed & Type-Safe FrameWork

Yuki NishikawaYuki Nishikawa
3 min read

Struggling with side effects in Next.js API Routes?
Tired of global middleware, nested folders, and cold starts that feel like winter?

Tirne is not just another framework.
It’s a declarative, type-safe DSL for building edge-first APIs — with fetch-native precision and architectural clarity.

🧠 Tirne doesn’t just run your code. It structures it.


✨ Core Philosophy

  • Structure as code — Routes, logic, middleware: all declarative

  • Explicit side effects — No magic. Middleware is opt-in, testable

  • Edge-native execution — Sub-millisecond cold starts on Bun and Workers

  • Types shape behavior — Runtime flows match your TypeScript design


🛠 Quick Start in 30 Seconds

npx create-tirne-app
️ Select target: › Bun / Workers
️ Project folder: › my-tirne-app

cd my-tirne-app
bun install   # or npm install
npm run dev   # or wrangler dev

🔥 Your first API is live in under a minute — at http://localhost:3000


⚡️ Performance: Benchmarks that Matter

MetricTirne (Bun)Next.js API Routes
❄️ Cold Start0.02 ms~300 ms
⚡️ First Request0.79 ms20-30 ms
🔁 RPS90k+8–10k
📉 Avg Latency<1 ms~15ms

✨ 10x faster, 100x simpler.


🧱 Hello, Structured APIs

import { Server } from "tirne";

const server = new Server([
  { method: "GET", path: "/health", handler: () => new Response("✅ OK") }
]);

export default {
  fetch: (req: Request) => server.fetch(req),
};

Compare that to folders, files, global config, and context spaghetti.


🔐 Real Auth, Without Magic

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", "token", {
        httpOnly: true,
        path: "/",
        maxAge: 3600,
      }));
      return json({ message: "Logged in" }, 200, headers);
    },
  },
  {
    method: "GET",
    path: "/private",
    handler: () => json({ message: "Secret" }),
    middleware: [requireAuth],
  },
];

✅ Auth should be visible, testable, and architectural — not magical.


❗️ Typed Errors, Clean Boundaries

import { Server, TirneError } from "tirne";

const routes = [
  {
    method: "GET",
    path: "/",
    handler: (req) => {
      const name = new URL(req.url).searchParams.get("name");
      if (!name) {
        throw new TirneError("Missing name", {
          status: 400,
          type: "bad_request",
          expose: true,
        });
      }
      return new Response(`Hello, ${name}`);
    },
  },
];

🪄 API errors are part of the contract — not a side effect.


🧠 Tirne is Built for Developers Who Want Clarity

  • No global context

  • No hidden decorators

  • No nested traps

Just pure, traceable code
Designed for speed. Shaped by types.
Architected like it matters.


⭐️ Try It Now


📣 Star Tirne if you're done guessing what your API does

We don’t need bigger frameworks.
We need smaller, sharper ones.

Less framework. More logic.
Welcome to the architectural era.

2
Subscribe to my newsletter

Read articles from Yuki Nishikawa directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Yuki Nishikawa
Yuki Nishikawa