Beignet
Contract-first TypeScript framework for building type-safe REST APIs, typed clients, validated application workflows, and OpenAPI output without codegen.
import { createContractGroup } from "@beignet/core/contracts";
import { z } from "zod";
const todos = createContractGroup()
.namespace("todos")
.prefix("/api/todos");
export const getTodo = todos
.get("/:id")
.pathParams(z.object({ id: z.string() }))
.responses({ 200: z.object({
id: z.string(),
title: z.string(),
completed: z.boolean(),
}) });
Beignet starts with the API contract and gives every production concern a clear place. Contracts define the HTTP boundary. Routes validate requests and responses. Use cases own business workflows. Ports describe what application code needs from the outside world. Infra adapters connect those ports to real services. Clients, React helpers, OpenAPI, and devtools reuse the same contract definitions.
Beignet is a framework. Start with the standard feature-first app layout, then let contracts, route registration, use cases, ports, clients, OpenAPI, and devtools stay connected as the app grows.
Start an app
bunx -p @beignet/cli beignet create my-app
cd my-app
bun install
cp .env.example .env.local
bun run dev
Then inspect the starter app:
bunx -p @beignet/cli beignet routes
bunx -p @beignet/cli beignet lint
bunx -p @beignet/cli beignet doctor
bun run typecheck
routes shows the contracts Beignet can match to route handlers. lint
checks dependency direction. doctor catches route, OpenAPI, and resource
drift. typecheck proves the app still matches its inferred contracts and
ports.
App map
| Area | Owns | Read next |
|---|---|---|
features/<feature>/contracts.ts | HTTP methods, paths, params, bodies, responses, headers, metadata, and catalog errors | Contracts |
features/<feature>/routes.ts | Contract-to-use-case route wiring owned by the feature | Routes and server |
features/<feature>/use-cases/ | Application workflows that run from HTTP, jobs, scripts, and tests | Use cases |
features/<feature>/domain/ | Feature-owned entities, value objects, and domain events under domain/events/ | Domain modeling |
features/<feature>/components/ | Feature-owned UI and client workflow surfaces | React, React Query |
features/<feature>/tests/ | Feature behavior tests for use cases, repositories, policies, and UI | Testing |
features/<feature>/ports.ts | Feature-specific dependency interfaces such as repositories | Ports and adapters |
features/<feature>/schedules/ | Feature-owned scheduled tasks for cron-triggered workflows | Scheduled tasks |
server/ | Context creation, route registration, providers, hooks, and error mapping | Routes and server, Request lifecycle |
app/api/ | Thin Next.js route files that expose server.api | App architecture |
domain/ | Optional shared-kernel domain concepts used across features | Domain modeling |
ports/ | App-owned dependency interfaces | Ports and adapters |
infra/ | Concrete adapters for databases, cache, storage, auth, mail, jobs, logging, rate limits, and other services | Providers |
client/ | Typed HTTP client and frontend adapter factories | Clients, React |
lib/env.ts | Validated deployment configuration | Config, Deployment |
What to read first
- Quickstart creates and inspects a new app.
- Build your first resource follows one generated feature through contracts, use cases, ports, infra, route files, and tests.
- App architecture explains where each production concern belongs.
Beignet's new
0.0.xpackage line is alpha. APIs may change between releases while the framework settles.