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

runtimekit

v1.0.5

Published

Composable runtime validation for TypeScript — define schemas once, infer static types automatically.

Downloads

545

Readme

runtimekit

Composable runtime validation for TypeScript.

runtimekit lets you define schemas as values, validate untrusted data at runtime, and derive static TypeScript types from those same definitions — no duplication required.


Install

npm install runtimekit

Requires Node.js 18 or later. Works with both ESM (import) and CommonJS (require).


Quick start

Define a schema, parse unknown input, and get a typed result:

import { Object, String, Number, Literal, Array, Static } from 'runtimekit';

const User = Object({
  id: Number,
  name: String,
  role: Literal('admin', 'member', 'guest'),
});

type User = Static<typeof User>;

const user = User.parse({ id: 1, name: 'Ada', role: 'admin' });
//    ^? User

If validation fails, parse throws a ValidationError with a readable message.


Core API

| Method | Behavior | |--------|----------| | parse(value) | Validate and return the typed value, or throw | | safeParse(value) | Return { success: true, value } or { success: false, error } | | test(value) | Type guard — returns true when the value matches | | assert(value) | Like parse, but accepts unknown and narrows the type | | serialize(value) | Validate and serialize to a plain JSON-safe value |


Building schemas

Schemas compose from primitives and combinators:

import {
  Boolean,
  Number,
  String,
  Literal,
  Union,
  Array,
  Tuple,
  Object,
  Intersect,
  Partial,
  Constraint,
} from 'runtimekit';

const Vector = Tuple(Number, Number, Number);

const Planet = Object({
  type: Literal('planet'),
  location: Vector,
  mass: Number,
  population: Number,
  habitable: Boolean,
});

const Positive = Constraint(Number, n => n > 0 || `${n} is not positive`);

const Fleet = Object({
  name: String,
  ships: Array(
    Object({
      name: String,
      crew: Number,
      position: Vector,
    }),
  ),
});

Unions and intersections

const Rank = Union(
  Literal('captain'),
  Literal('officer'),
  Literal('ensign'),
);

const RegisteredShip = Intersect(
  Fleet,
  Object({ isRegistered: Literal(true) }),
  Partial({ classification: Union(Literal('military'), Literal('civilian')) }),
);

Optional and nullable fields

import { Union, Undefined, Null, Nullable } from 'runtimekit';

const MaybeString = Union(String, Undefined);   // string | undefined
const NullableString = Nullable(String);          // string | null

const Profile = Object({ bio: String }).And(
  Partial({ website: Union(String, Undefined) }),
);

Type inference

Use Static<typeof Schema> to derive a TypeScript type from any schema:

import { Static } from 'runtimekit';

type Planet = Static<typeof Planet>;
// { type: 'planet'; location: [number, number, number]; mass: number; ... }

Type guards

Use schemas as runtime type guards:

function handle(input: unknown) {
  if (Planet.test(input)) {
    // input is narrowed to Planet
    console.log(input.population);
  }
}

Constraints and custom validators

Add arbitrary runtime checks with Constraint:

const Email = Constraint<string, `${string}@${string}`>(
  String,
  value => value.includes('@') || 'Invalid email address',
  { name: 'Email' },
);

For custom types backed by a type guard:

import { Guard } from 'runtimekit';

const BufferSchema = Guard(Buffer.isBuffer, { name: 'Buffer' });

Readonly schemas

Wrap any schema with Readonly to produce immutable inferred types:

import { Readonly, ReadonlyArray } from 'runtimekit';

const ImmutablePlanet = Readonly(Planet);
type ImmutablePlanet = Static<typeof ImmutablePlanet>;
// { readonly type: 'planet'; readonly location: readonly [number, number, number]; ... }

Import from runtimekit/readonly to default all collection helpers to their readonly variants:

import { Object, Array, Tuple } from 'runtimekit/readonly';
// Object, Array, and Tuple produce readonly types by default

Object utilities

Mirror TypeScript's built-in object utilities:

import { Partial, Pick, Omit } from 'runtimekit';

const PartialPlanet = Partial(Planet);
const PlanetMass = Pick(Planet, ['mass']);
const PlanetWithoutMass = Omit(Planet, ['mass']);

Safe parsing

Prefer non-throwing validation at API boundaries:

const result = User.safeParse(untrusted);

if (result.success) {
  console.log(result.value.name);
} else {
  console.error(result.error);
}

License

MIT © yuliahrabets