npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@routepact/core

v0.1.13

Published

Type-safe route spec definitions shared between server and client

Downloads

1,714

Readme

@routepact/core

Shared types and utilities for defining type-safe route pacts. This package is the contract between your server and client - import it in shared code that both sides depend on.

Installation

npm install @routepact/core

You also need a schema library that implements the Standard Schema interface (e.g. Zod, Valibot, ArkType). Examples below use Zod but any Standard Schema-compatible library works.

npm install zod    # or valibot, arktype, etc.

Defining a pact

A pact describes a single endpoint: its path, HTTP method, and optional validation schemas for the request body, response body, query parameters, path parameters, and response metadata. Schemas must implement the Standard Schema interface.

Use definePact to get full type inference while keeping literal types (exact path strings, method literals):

import { z } from "zod";
import { definePact } from "@routepact/core";

export const PostPacts = {
  list: definePact({
    method: "get",
    path: "/posts",
    response: z.object({
      items: z.object({ id: z.string(), title: z.string() }).array(),
      total: z.number(),
      page: z.number(),
    }),
    query: z.object({
      page: z.string().optional(),
      limit: z.string().optional(),
    }),
  }),
  getById: definePact({
    method: "get",
    path: "/posts/:id",
    response: z.object({
      id: z.string(),
      title: z.string(),
      body: z.string(),
    }),
  }),
  create: definePact({
    method: "post",
    path: "/posts",
    request: z.object({ title: z.string(), body: z.string() }),
    response: z.object({
      id: z.string(),
      title: z.string(),
      body: z.string(),
    }),
  }),
  update: definePact({
    method: "patch",
    path: "/posts/:id",
    request: z.object({
      title: z.string().optional(),
      body: z.string().optional(),
    }),
    response: z.object({
      id: z.string(),
      title: z.string(),
      body: z.string(),
    }),
  }),
  delete: definePact({
    method: "delete",
    path: "/posts/:id",
  }),
};

Validation schemas

| Field | Required for | Description | | ---------- | ------------------------------- | ----------------------------------------------------------------- | | request | Only for post, patch, put | Object schema for req.body on the server | | response | Optional | Object schema for the full response body sent via res.json(...) | | query | Optional | Object schema for query parameters - typed on both server and client |

All validation schemas must describe object types (e.g. z.object(...) in Zod) - routepact is opinionated that request bodies, responses, and query parameters are always objects. Primitive or array schemas are not supported at the pact level.

Path parameters

Parameters in the path (:param) are extracted as a type-safe object. If a path contains :id, the params option is required and typed as { id: string }.

// TypeScript requires params when the path has parameters
await request(PostPacts.getById, { params: { id: "abc" } });

// TypeScript forbids params when there are none
await request(PostPacts.list);

On the server, ctx.params is automatically populated from the URL and typed as { [key: string]: string } based on the path string - no Zod schema needed.

Query parameters

Add a query schema to make query parameters type-safe on both server and client. If any field in the schema is required, TypeScript will require the query option at the call site:

const list = definePact({
  method: "get",
  path: "/posts",
  query: z.object({ page: z.string().optional(), sort: z.string() }), // sort is required
});

// TypeScript requires query.sort
await request(list, { query: { sort: "createdAt" } });

Type reference

| Type | Description | | ----------------------------- | ------------------------------------------------------------------------------------------------- | | RoutePact | Generic type for a single pact definition | | AnyRoutePact | Widened pact type - used internally and in package integrations | | AnyRouteValidation | The set of optional Standard Schema-compatible schemas that can be attached to a pact | | HttpMethod | "get" \| "post" \| "patch" \| "put" \| "delete" | | RouteOptions<TPact> | Inferred call-site options (params, payload, query) for a pact | | RouteOptionsRequired<TPact> | true if options are required (pact has params or a request schema) | | QueryOption<TPact> | Inferred query option - required if the query schema has required fields | | PactRequest<TPact> | Inferred output type of the request body - never if the pact has no request schema | | PactInputRequest<TPact> | Inferred input type of the request body (before transforms) - never if no request schema | | PactParams<TPact> | Inferred path parameter record - never if the path has no :param segments | | PactQuery<TPact> | Inferred output type of query parameters - never if the pact has no query schema | | PactInputQuery<TPact> | Inferred input type of query parameters (before transforms) - never if no query schema | | PactResponse<TPact> | Inferred response type - the schema's output type when a response schema is defined, never otherwise | | ExtractParams<TPath> | Extracts parameter names from a path string | | ExpectedParams<TPath> | Maps extracted param names to string values |