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

@contractkit/plugin-typescript

v0.18.0

Published

ContractKit built-in plugin: TypeScript codegen (SDK clients, Koa routers, Zod schemas, plain types)

Readme

@contractkit/contractkit-plugin-typescript

ContractKit plugin that generates TypeScript output from .ck contract files. Covers all server-side and client-side TypeScript needs: Koa routers, SDK clients, Zod schemas, and plain TypeScript interfaces.

Installation

pnpm add @contractkit/contractkit-plugin-typescript

Configuration

Add the plugin to contractkit.config.json. Each sub-config is independent — include only what you need.

{
  "plugins": {
    "@contractkit/contractkit-plugin-typescript": {
      "server": {
        "baseDir": "apps/api/",
        "zod": true,
        "output": {
          "routes": "src/routes/{filename}.router.ts",
          "types": "src/modules/{area}/types/{filename}.ts"
        },
        "servicePathTemplate": "#modules/{module}/{module}.service.js"
      },
      "sdk": {
        "baseDir": "packages/sdk/",
        "name": "acme",
        "zod": true,
        "output": {
          "sdk": "src/{name}.sdk.ts",
          "types": "src/{area}/types/{filename}.ts",
          "clients": "src/{area}/{filename}.client.ts"
        }
      },
      "zod": {
        "baseDir": "packages/schemas/",
        "output": "{filename}.schema.ts"
      },
      "types": {
        "baseDir": "packages/types/",
        "output": "{filename}.types.ts"
      }
    }
  }
}

Sub-configs

server

Generates Koa router files from operation declarations and optionally type files from contract declarations.

| Option | Type | Default | Description | |---|---|---|---| | baseDir | string | rootDir | Base directory for output files | | zod | boolean | false | Emit Zod schemas in output.types instead of plain interfaces | | output.routes | string | — | Path template for router files | | output.types | string | — | Path template for type/schema files | | servicePathTemplate | string | — | Import path template for service implementations |

Each generated router imports handler implementations from a service module. The servicePathTemplate controls where that import points. Template variables: {module}.

sdk

Generates a typed TypeScript SDK client from operation declarations. Produces individual client files per operation file plus an aggregator SDK class.

| Option | Type | Default | Description | |---|---|---|---| | baseDir | string | rootDir | Base directory for output files | | name | string | "sdk" | SDK class name (e.g. "acme"AcmeSdk) | | zod | boolean | false | Emit Zod schemas in output.types instead of plain interfaces | | output.sdk | string | — | Path template for the aggregator SDK file | | output.types | string | — | Path template for type/schema files | | output.clients | string | — | Path template for individual client files |

zod

Generates standalone Zod schema files from contract declarations only. Use this when you want schemas without any router or SDK output.

| Option | Type | Default | Description | |---|---|---|---| | baseDir | string | rootDir | Base directory for output files | | output | string | "{filename}.schema.ts" | Path template for schema files |

types

Generates plain TypeScript interface/type files from contract declarations. No Zod runtime dependency.

| Option | Type | Default | Description | |---|---|---|---| | baseDir | string | rootDir | Base directory for output files | | output | string | "{filename}.types.ts" | Path template for type files |

Path templates

Output paths support the following variables:

| Variable | Value | |---|---| | {filename} | Base name of the .ck source file (without extension) | | {dir} | Relative directory of the .ck source file | | {area} | Value of the area key from the options block | | {subarea} | Value of the subarea key from the options block | | {name} | The name option from the SDK sub-config |

What gets generated

Zod schema shape (from contract)

Contracts with readonly or writeonly fields generate up to three schemas:

  • ModelBase — all fields including writeonly (only when writeonly fields exist)
  • Model — read schema; no writeonly fields; extends ModelBase when it exists
  • ModelInput — input schema; no readonly fields (only when readonly/writeonly fields exist)

Contracts without visibility modifiers generate a single Model schema.

Koa router shape (from operation)

Each operation file generates one Koa router. Request bodies and path/query params are validated against the Zod schemas (when zod: true) or plain types. Handlers are expected to be exported from the service module specified by servicePathTemplate.

SDK client shape (from operation)

Operation files cluster on the SDK based on keys.area and keys.subarea (set in each file's options { keys: { ... } } block):

| File metadata | Generated layout | | --- | --- | | area: identity, subarea: invitations | leaf IdentityInvitationsClient emitted as <output.clients> (path can use {subarea}); aggregator wires it as sdk.identity.invitations | | area: identity (no subarea) | methods inlined directly on IdentityClient (no standalone *.client.ts); exposed as sdk.identity.<method> | | neither | flat <Filename>Client exposed as sdk.<filename> (legacy behavior) |

Multiple files mapping to the same (area, subarea) are merged into one leaf class. Multiple area-level files merge into a single <Area>Client; duplicate method names across them throw at codegen — disambiguate with sdk: or move one into a subarea.

Method names follow this priority:

  1. sdk: field on the HTTP verb declaration — used as-is (e.g. sdk: getUsergetUser)
  2. name: field — converted to camelCase (e.g. name: "Get User"getUser)
  3. Inferred from the HTTP method and path (e.g. GET /users/{id}getUsersById)

A shared sdk-options.ts file is emitted alongside the clients. It exports:

  • SdkOptions / SdkFetch / SdkError / createSdkFetch — base client primitives
  • buildQueryString(query) — serialises a query params object to ?key=value or ''
  • parseJson<T>(res) — deserialises a Response body to T
  • bigIntReplacer / bigIntReviver — JSON replacer/reviver for bigint values

Programmatic use

import { createTypescriptPlugin } from '@contractkit/contractkit-plugin-typescript';

const plugin = createTypescriptPlugin({
  server: {
    output: { routes: 'src/routes/{filename}.router.ts' },
    servicePathTemplate: '#services/{module}.service.js',
  },
});