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

@ir-kit/fn-schema-typescript

v0.1.1

Published

TypeScript extractor for fn-schema. Walks source via ts-morph, synthesizes virtual type aliases for each function's parameters and return, then converts them to JSON Schema via ts-json-schema-generator. Re-exports a pre-wired `extract` for single-language

Readme

@ir-kit/fn-schema-typescript

TypeScript extractor for fn-schema. The default TS implementation of the Extractor contract from core.

Most users don't import this directly — they use the cli. Reach for the programmatic API when you're building tooling on top of fn-schema.

Install

pnpm add @ir-kit/fn-schema-typescript

Quick start

import { extract } from "@ir-kit/fn-schema-typescript"

const result = await extract({
  files: ["src/api/handlers.ts"],
  tsConfigPath: "./tsconfig.json",
})

for (const sig of result.signatures) {
  console.log(sig.id, sig.input, sig.output)
}

extract is a one-shot helper. For repeat calls (server endpoints, dev mode, watch), use createProject from core directly with typescript() as the extractor — it keeps the ts-morph project warm.

What it discovers

  • function foo() {} declarations
  • const foo = () => {} and const foo = function() {}
  • Class methods (instance + static, exported classes)
  • Object-literal members: export const api = { create() {}, tag: () => {} }
  • Default-export arrows: export default (input) => {}
  • Function and method overloads (configurable via signature.overloads)
  • this parameter is auto-skipped

What it extracts

  • Multi-parameter functions — signature.parameters controls layout (array / first-only / object)
  • Async returns — Promise<T> auto-unwrapped (toggle via signature.unwrapPromise)
  • Generic functions — skipped by default (set signature.generics: "erase" to coerce to unknown)
  • Branded types (type X = string & { __brand: "X" }) — phantom stripped, identity preserved when the keyword is on
  • Well-known types canonicalized: Date, URL, RegExp, File, Blob, Buffer, Uint8Array, ArrayBuffer, bigint
  • symbol and function-as-input → NOT_REPRESENTABLE diagnostic

Filters

extract({
  files: ["src/api/**/*.ts"],
  include: {
    exported: true,
    name: /^create/,
    jsDocTag: "schema",
    kind: ["function", "method"],
  },
  exclude: { name: /^_/, jsDocTag: "internal" },
  filter: (fn) => fn.async,
})

How the type resolution works

For each function we synthesize a virtual TS file alongside it:

// src/__fn_schema_virtual__/handlers_createUser.virtual.ts
import type { CreateUserInput, User } from "../handlers"

type __FnSchemaMap_Date = { readonly __fn_schema_marker: "Date" }

export type __In_0 = CreateUserInput
export type __Out__ = Awaited<Promise<User>>

ts-json-schema-generator processes this like any other source file. Sentinel object types (__FnSchemaMap_Date, etc.) survive union flattening because they're structurally distinct from primitives. After generation, a post-process pass swaps each sentinel for its canonical schema and (optionally) attaches identity/transport/source-location keywords.

This indirection is what lets fn-schema reuse ts-json-schema-generator without forking it — we work around its inability to resolve Parameters<typeof X> and import("path").Y by emitting bare type identifiers and resolving cross-file imports ourselves.

Diagnostics

Subscribe via extract({ onDiagnostic: (d) => ... }) or read result.diagnostics. Codes are documented in core/README.md.