Skip to content

mbrimmer83/ts-contract

Repository files navigation

ts-contract

CI PR Checks

🚧 This project is under active development and not yet ready for production use. No alpha version has been published.

An opinionated schema-first TypeScript contract library for defining type-safe HTTP and WebSocket APIs.

Why ts-contract?

Minimal by design. No framework integrations.

Every integration adds surface area, complexity, and long-term maintenance burden. ts-contract stays focused on a small, durable core with first-class TypeScript inference and composable primitives that make it easy to integrate with any stack.

  • Small core. Zero integrations. — No lock-in to any server or client framework.
  • Schema-first. — Define your API shape with the validation library you already use.
  • Excellent TypeScript inference. — Extract path params, query, body, headers, and response types from your contract.
  • Composable primitives. — Add capabilities through a plugin system, not monolithic abstractions.
  • Integrate it your way. — Use the inference types to wire up Hono, Express, Fastify, React Query, or anything else.
  • Supports @standard-schema/spec. — Works with Zod, Valibot, Arktype, and any Standard Schema compliant library.

Quick Example

import { createContract, initContract } from '@ts-contract/core';
import { pathPlugin, validatePlugin } from '@ts-contract/plugins';
import { z } from 'zod';

const contract = createContract({
  getUser: {
    method: 'GET',
    path: '/users/:id',
    pathParams: z.object({ id: z.string() }),
    responses: {
      200: z.object({
        id: z.string(),
        name: z.string(),
        email: z.string().email(),
      }),
      404: z.object({ message: z.string() }),
    },
  },
});

const api = initContract(contract).use(pathPlugin).use(validatePlugin).build();

// Type-safe URL construction
const url = api.getUser.buildPath({ id: '123' });
// => "/users/123"

// Runtime validation against your schema
const user = api.getUser.validateResponse(200, data);
// => { id: string, name: string, email: string }

WebSocket Example

import { createContract, initContract } from '@ts-contract/core';
import {
  websocketPathPlugin,
  websocketValidatePlugin,
} from '@ts-contract/plugins';
import { z } from 'zod';

const contract = createContract({
  chat: {
    type: 'websocket',
    path: '/ws/chat/:roomId',
    pathParams: z.object({ roomId: z.string() }),
    query: z.object({ token: z.string() }),
    clientMessages: {
      new_msg: z.object({
        type: z.literal('new_msg'),
        body: z.string(),
      }),
    },
    serverMessages: {
      new_msg: z.object({
        type: z.literal('new_msg'),
        id: z.string(),
        body: z.string(),
        userId: z.string(),
      }),
    },
  },
});

const api = initContract(contract)
  .useWebSocket(websocketPathPlugin)
  .useWebSocket(websocketValidatePlugin)
  .build();

// Build WebSocket URL
const url = api.chat.buildPath({ roomId: '123' }, { token: 'abc' });
// => "/ws/chat/123?token=abc"

// Validate outgoing message
const msg = api.chat.validateClientMessage('new_msg', {
  type: 'new_msg',
  body: 'Hello!',
});

// Validate incoming message (e.g., with Phoenix.js)
channel.on('new_msg', (data) => {
  const validated = api.chat.validateServerMessage('new_msg', data);
  console.log(validated.body);
});

Packages

Package Description
@ts-contract/core Contract definitions, type inference helpers, and plugin system
@ts-contract/plugins Built-in plugins for path building and schema validation

Documentation

Documentation is available at the docs site (coming soon).

To run the docs locally:

pnpm install
pnpm --filter @ts-contract/docs dev

Development

This is a monorepo using pnpm workspaces.

# Install dependencies
pnpm install

# Build all packages
pnpm -r build

# Run tests
pnpm -r test

# Run docs dev server
pnpm --filter @ts-contract/docs dev

Contributing

We welcome contributions! Please see our Contributing Guide for details on:

  • Setting up your development environment
  • Our development workflow
  • How to create changesets for version management
  • Pull request process
  • Release process

License

MIT

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages