Skip to content
Lugas logo

LugasJS

Explicit, Bun-native typed HTTP APIs — without runtime proxies, code generation, or production dependencies.

Getting started · Examples · Compatibility · Roadmap

CI Release channel: beta Bun 1.4.x TypeScript 7.0.x Zero runtime dependencies License: Apache-2.0

Status and install

Lugas uses the beta dist-tag for prerelease builds. Check npm or GitHub Releases for the currently available version.

For published beta builds:

bun add lugas@beta

Requires Bun 1.4.x; TypeScript 7.0.2 is the verified toolchain for the full compile-time contract experience.

30-second example

// app.ts
import { defineApp, json, route } from "lugas";

const app = defineApp({
  routes: {
    "/hello": {
      GET: route({
        handler: () => json(200, { message: "Hello from Lugas" }),
      }),
    },
  },
});

export default app;
// server.ts
import app from "./app";

const server = app.serve({ port: 3000 });
console.log(`Lugas is listening on ${server.url}`);
bun run server.ts
curl http://localhost:3000/hello

Routes stay ordinary HTTP: native Request, explicit statuses, real fetch underneath.

Validation and guards compose per route; schema outputs and guard enrichments arrive typed on the handler context:

import { defineApp, defineModule, guard, json, route } from "lugas";
import { z } from "zod"; // any Standard Schema v1 validator works

const auth = guard({
  name: "auth",
  handler: (ctx) => {
    if (!ctx.request.headers.get("authorization")) return json(401, { error: "unauthorized" });
    return { user: { id: "u_1" } };
  },
});

export default defineApp({
  modules: [
    defineModule({
      name: "invoices",
      routes: {
        "/invoices": {
          POST: route({
            before: [auth],
            body: z.object({ amount: z.number().positive(), currency: z.string().length(3) }),
            handler: (ctx) => json(201, { id: "inv_1", amount: ctx.body.amount, user: ctx.user.id }),
          }),
        },
      },
    }),
  ],
});

Why Lugas?

Most TypeScript frameworks sit at one of two extremes: a thin router that leaves all structure to you, or a large platform with decorators, proxies, and generated clients. Lugas takes a narrower path — keep HTTP explicit, add only the structure that makes Bun applications predictable, typed, testable, and inspectable:

  • typed routes with status-discriminated, wire-honest response types;
  • Standard Schema v1 validation (Zod, Valibot, …) with schema-derived handler types;
  • ordered guards with typed context enrichment;
  • RFC 9457 Problem Details errors with stable diagnostic codes;
  • an end-to-end typed client — no code generation, no runtime Proxy;
  • zero production runtime dependencies.

Full positioning and framework comparisons: docs/choosing-lugas.md.

Typed client (lugas/client)

import type { AppContract } from "lugas";
import { createClient } from "lugas/client";
import type app from "./app";

const api = createClient<AppContract<typeof app>>({ baseUrl: "https://api.example.com" });

const result = await api.post("/invoices", {
  body: { amount: 125, currency: "USD" },
});

if (result.ok) {
  console.log(result.status, result.data.id);
} else {
  console.error(result.status, result.error); // Problem Details on 4xx/5xx
}

Types describe the wire. A handler returning json(200, { createdAt: new Date() }) is observed by the client as { createdAt: string } — non-finite numbers, toJSON() drops, and throws are all modeled, not hidden. Details: docs/wire-honest-types.md.

Features

Capability Status
Bun-native server, typed routes, modules Available
Standard Schema validation on params/query/headers/body Available
Ordered guards with typed context enrichment Available
Status-discriminated, wire-honest responses (json/text/problem/empty) Available
RFC 9457 Problem Details + redacted 500s Available
End-to-end typed client (lugas/client, browser-safe) Available
Service lifecycle: init, drain-ordered shutdown, reverse disposal (service()) Available
Test-server helpers (lugas/testing) Available
Static route manifest + inspection CLI (lugas-manifest-v1) Available
First-party CORS (defineApp({ cors }), opt-in, fail-closed) Available in 0.1.0-beta.2 (M8-001)
Server-Sent Events (sse() helper, deterministic cleanup) Available in 0.1.0-beta.2 (M8-002)
Structured logging (defineApp({ logging }), sink contract) Available in 0.1.0-beta.2 (M8-003)
OpenAPI 3.1 + Scalar reference UI (defineApp({ openapi }), zero-dependency) Available in 0.1.0-beta.2 (M8-004)
Drizzle ORM adapter (lugas/drizzle, application-owned instance) Available in 0.1.0-beta.3 (M9-001)
Cookie primitives (parseCookies/cookie, RFC 6265, auth-interop recipe) Shipped on main (M9-002)
WebSockets (websocket() routes, pre-upgrade guards, shutdown close-1001) Shipped on main (M9-003)
Secure headers + health/readiness (secureHeaders, health) Shipped on main (M9-004)

Examples

Runnable, single-concept applications under examples/ — indexed in examples/README.md:

Example Demonstrates
basic Minimal app: routes, JSON/text, redirect, Problem Details
validation Zod + Valibot across params, query, headers, body
auth Ordered guards: 401/403 short-circuits, context enrichment
client Typed client round-trip against a live test server
proof-api Realistic CRUD API combining all of the above

Compatibility

Verified matrix (see docs/compatibility.md): Bun 1.4.x on Linux x86-64, macOS arm64, and Windows x64; TypeScript 7.0.2; Zod 4.4.3 and Valibot 1.4.2 (any Standard Schema v1 validator works). Browser-safe client bundle plus a prebuilt browser artifact (lugas/client/browser) verified in a same-origin real-browser lane; real browsers are not part of the per-OS CI matrix.

Known beta limitations: the server core and CLI are Bun-only (the client bundle is runtime-neutral), declarations ship as direct .ts sources, and in-flight handler work is not cancelled on client disconnect.

Roadmap

Shipped and planned work lives in docs/roadmap.md. The Drizzle adapter (docs/drizzle.md) ships in lugas@0.1.0-beta.3 (published under npm beta, source commit f3c72e6, M9-001). First-party CORS (docs/cors.md), Server-Sent Events (docs/sse.md), Structured Logging (docs/logging.md), and OpenAPI 3.1 + Scalar (docs/openapi.md) ship in 0.1.0-beta.2+; latest points at 0.1.0-beta.2.

Documentation

Document Contents
docs/getting-started.md Install, first app, validation, guards, client, testing, CLI
docs/routing.md Route maps, path syntax, modules, native values, the derived handler context
docs/validation.md Standard Schema slots, coercion, body parsing, the 422 failure contract
docs/guards.md Ordered guards, typed context enrichment, short-circuits, composition patterns
docs/responses.md Typed response helpers, Problem Details, notFound/onError, redaction
docs/services.md Named dependencies, service() lifecycle, the init traffic gate, drain shutdown
docs/client.md The end-to-end typed client: calls, per-status results, error classes
docs/testing.md createTestServer, the bound typed client, lifecycle and error-contract tests
docs/wire-honest-types.md How response types model JSON serialization truth
docs/design-principles.md Explicit HTTP, no codegen, no proxies, zero forced ecosystem
docs/choosing-lugas.md Fit and comparison with raw Bun, Elysia, Hono, Fastify, tRPC
docs/api-reference.md Public API reference
docs/diagnostics.md Diagnostic code catalog (LUGAS_*)
docs/manifest-v1.md Frozen lugas-manifest-v1 schema
docs/client-error-semantics.md Client error and redaction policy
docs/drizzle.md Drizzle integration: application-owned instance as a service
docs/cookies.md Cookie primitives and the Better Auth interop recipe
docs/websockets.md WebSocket routes: pre-upgrade guards, native sockets, shutdown semantics
docs/production.md Production hardening: secure headers and health/readiness
docs/performance-gates.md Release performance budgets and evidence policy
CHANGELOG.md Release history
Release evidence Candidate evidence packet, provenance, and checksums (GitHub)

Agent-facing context: llms.txt and llms-full.txt. Governance, delivery history, and architecture decisions live under docs/okf/; implementation evidence under docs/reports/.

Contributing and security

Contributions follow the worktree + verify-gate workflow in CONTRIBUTING.md — real-application feedback, type-inference reproductions, and cross-platform reports are the highest-value contributions during beta. Community rules: CODE_OF_CONDUCT.md. Questions and support: SUPPORT.md.

Do not open public issues for security vulnerabilities — report privately per SECURITY.md.

License

Apache-2.0 — see LICENSE and NOTICE.

About

Explicit, Bun-native typed HTTP APIs without proxies or code generation.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages