@torkjs/core
v0.1.3
Published
Bun-native, type-safe, blazingly fast backend framework with end-to-end type inference and zero boilerplate.
Maintainers
Readme
Tork is a modern, fast (high-performance) backend framework for building APIs with Bun and TypeScript, based on standard TypeBox / JSON Schema.
The key features are:
- Fast: Very high performance, on par with Elysia and far ahead of Hono and Fastify. One of the fastest Bun frameworks available.
- Type safe: End-to-end inference. The handler context is derived from the
query/headers/body/params/responseschemas and the injected services, with no per-route annotation. - OpenAPI for free: TypeBox schemas are native JSON Schema, so
/docsSwagger UI and/openapi.jsoncome out of the box. - Batteries included: JWT auth, guards, middleware (CORS, compress, CSRF, rate limit, static files), cron, queue, cache, sessions, SSE, and WebSockets.
- Production networking: The full power of
Bun.serve— HTTPS with support for both HTTP/2 and HTTP/3 (QUIC), unix sockets, andreusePortfor OS-level load balancing. - Nested DI: Zero-boilerplate singleton services via
Injectable, plus portable feature modules. - Fail fast:
BaseSettings-style config that is coerced and validated at boot, so the app refuses to start on an invalid or missing value. - Easy to test: An in-process
testClient(no port, no network) for fast, isolated tests.
Sponsors
Tork is free and open source. If it helps you ship, consider sponsoring development.
Requirements
Tork stands on the shoulders of Bun:
- Bun >= 1.3.14 for the runtime parts: the server (
Bun.serve), scheduled jobs (Bun.cron), Redis (Bun.redis), and Web Crypto. - TypeBox for the data parts. It is the single runtime dependency; everything else is a Bun built-in.
Installation
Scaffold a new project with the CLI:
bunx @torkjs/cli new my-api
# or install it globally
bun add -g @torkjs/cli
tork new my-apiAdd Tork to an existing project:
bun add @torkjs/coreExample
A small app.ts, focused on the route structure:
import { t, Tork, TorkRouter } from "@torkjs/core";
// Assume we already have the schemas and services, in their own files.
import { CreateUser, UserOut } from "./schemas/user.ts";
import { Book } from "./schemas/book.ts";
import { UserService } from "./services/user.service.ts";
import { BookService } from "./services/book.service.ts";
// --- Each feature is its own router (the ctx is inferred from schemas + inject) ---
const users = new TorkRouter("/users", { tags: ["users"] });
users.get(
"/",
{ response: t.Array(UserOut), inject: { userService: UserService } },
({ userService }) => userService.list(),
);
users.post(
"/",
{ body: CreateUser, response: UserOut, inject: { userService: UserService } },
({ body, userService }) => userService.create(body),
);
const books = new TorkRouter("/books", { tags: ["books"] });
books.get(
"/",
{ response: t.Array(Book), inject: { bookService: BookService } },
({ bookService }) => bookService.list(),
);
// --- Nest every feature under one /api router ---
const api = new TorkRouter("/api");
api.includeRouter(users).includeRouter(books); // -> /api/users, /api/books
new Tork({ title: "My API", version: "1.0.0", docs: "/docs" }).includeRouter(api).listen(8787);