Skip to main content

What is Contract Kit?

Contract Kit is a contract-first TypeScript framework for building type-safe APIs and typed clients without codegen. It works with any Standard Schema library (Zod, Valibot, ArkType, etc.).
Prototype / Exploratory: APIs may change frequently before 1.0.

Key Features

Type-Safe Contracts

Define HTTP contracts once and get end-to-end type safety across your entire stack

No Codegen

No build steps or code generation required - just runtime validation and TypeScript inference

Standard Schema Support

Works with Zod, Valibot, ArkType, or any Standard Schema library

Clean Architecture

Built-in support for hexagonal architecture with ports and providers

What You Get

Contract Kit provides a comprehensive toolkit for building modern TypeScript applications:
  • Contracts: Define method, path, schemas (path/query/body/response/errors), and metadata
  • Server runtime: Adapter-agnostic request pipeline with parsing, validation, middleware, and error mapping
  • Server adapters: Next.js support (with more coming)
  • Client: Typed fetch wrapper driven by the same contract
  • Application layer: Use cases with commands and queries
  • Ports + Providers: Hexagonal-style dependency injection (db, mail, cache, rate limit, jobs, logging…)
  • OpenAPI: Generate OpenAPI 3.1 specifications from your contracts
  • Optional React: TanStack Query + React Hook Form helpers

Philosophy

Contract Kit is designed around these principles:
  1. Contracts as the source of truth - Define once, use everywhere
  2. Avoid code generation - Leverage TypeScript’s type system for inference
  3. Support clean architecture - Built with hexagonal architecture in mind
  4. Stay modular - Use the entire framework or just the pieces you need
  5. Scale from MVPs to production - Start simple, grow as needed

Quick Example

import { createContractGroup } from "contract-kit";
import { z } from "zod";

const todos = createContractGroup().namespace("todos");

export const getTodo = todos
  .get("/api/todos/:id")
  .path(z.object({ id: z.string() }))
  .response(200, z.object({
    id: z.string(),
    title: z.string(),
    completed: z.boolean(),
  }));

Acknowledgements

Contract Kit is inspired by and builds upon ideas from several excellent projects:
  • tRPC – for pioneering end-to-end type safety without codegen in TypeScript
  • ts-rest – for demonstrating contract-first REST APIs with TypeScript
  • Laravel – for showing how framework elegance and developer experience can coexist with power and flexibility
We’re grateful to these projects and their communities for paving the way.