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

@lyku/para-schema

v0.0.1-pre.0

Published

Para schema type system + portable runtime — JSON Schema 2020-12 with 1:1 brand-type parity. `fromSchema` validates off ParaBun (browsers, Cloudflare Workers, Node), where ParaBun's own fallback is the identity function. Ships two type variants: extended

Readme

@lyku/para-schema

JSON Schema 2020-12 with 1:1 TypeScript brand-type parity.

Two variants, one package

| Audience | Resolves to | What you get | | ---------------------------- | ------------------------- | ----------------------------------------------------------- | | .pts / Para projects | src/index.ts | Full constraint brands (StringOf<{ minLength: 3 }>, etc.) | | Vanilla TS / Node consumers | src/index.standard.ts | Same names, all collapse to base primitives (string, number, …) |

The split is implemented via the parabun package-export condition:

// In a Para-aware tsconfig.json:
{
  "compilerOptions": {
    "moduleResolution": "bundler",
    "customConditions": ["parabun"]
  }
}

When customConditions includes "parabun", tsc resolves to the extended variant. Without it, vanilla TS resolves to the standard variant. The exported names are identical in both files, so a .d.ts emitted by gen-dts-rewrite works unchanged in either audience — only the constraint expressivity changes.

Surface

import type {
  // Brands
  StringOf, NumberOf, BigIntOf, BooleanOf, ArrayOf, ObjectOf, Brand,
  // Schema runtime types
  SchemaValue, Schema, Infer, InferFromSchema, Result,
  // Helpers
  Handles,
} from "@lyku/para-schema";

Constraint brands

type Username   = StringOf<{ minLength: 3; maxLength: 32; pattern: "^[A-Za-z0-9_]+$" }>;
type Email      = StringOf<{ format: "email" }>;
type Age        = NumberOf<{ integer: true; minimum: 0; maximum: 150 }>;
type Snowflake  = BigIntOf<{ minimum: 0n }>;
type Tags       = ArrayOf<string, { minItems: 1; maxItems: 10 }>;

In the extended variant these are structurally distinct from their base types — you can't pass a raw string where Username is expected. In the standard variant they all collapse to string/number/etc. and the constraints are dropped silently.

Schema values + Handles<…>

import type { Handles } from "@lyku/para-schema";

const getUser = {
  request:  schema { type: "object", properties: { id: { type: "bigint" } }, required: ["id"] },
  response: schema { type: "object", properties: { name: { type: "string" } }, required: ["name"] },
};

const handler: Handles<typeof getUser, AppCtx> = (req, ctx) => {
  // req: { id: bigint } — derived from request schema
  // return: { name: string } — derived from response schema
  return { name: `user${req.id}` };
};

fromSchema — the portable runtime

import { fromSchema } from "@lyku/para-schema";

const Workspace = fromSchema({
  type: "object",
  properties: { name: { type: "varchar", maxLength: 120 } },
  required: ["name"],
  additionalProperties: false,
} as const);

Workspace.parse({ name: "Lyku" });        // { tag: "Ok", value: { name: "Lyku" } }
Workspace.parse({ name: 42 });            // { tag: "Err", error: "name: expected string" }
Workspace.is({ name: "Lyku" });           // true
Workspace.name.maxLength;                 // 120 — field navigation

Why this exists. On ParaBun, schema NAME = { … } lowers to the built-in validator in the Bun fork. Off ParaBun, ParaBun's own fallback is __paraFromSchema = (schema) => schema — the identity function. A schema shipped to a browser or a Cloudflare Worker therefore validated nothing at all. fromSchema is a faithful, dependency-free port of that validator, so the same schema gates data on the edge and in the client exactly as it does on the server.

Codegen that already knows the resolved TS type supplies it explicitly, skipping brand inference:

export const organization = fromSchema<typeof body, Organization>(body);

The body's own keys stay enumerable (so { ...Workspace } is a plain JSON Schema again, safe to embed in another schema literal); parse, validate, is, schema, and the field accessors are non-enumerable.

Dialect

JSON Schema 2020-12 plus the Para/Postgres type tags, so a lockstep record model is already a valid body: bigint, snowflake, varchar, text, char, numeric, timestamptz, date, jsonb, enum. required means NOT NULL — an omitted key is nullable, and a present null fails a required field. A record with properties and no explicit type is treated as an object.

Composition is by embedding: a sub-schema that is itself a wrapped schema (it has .parse) validates itself. The portable runtime has no module $ref registry, so a string $ref throws rather than silently passing — an unresolvable reference must never read as "valid".

Two places this validator is deliberately stricter than ParaBun's, both cases where ParaBun is permissive by omission rather than by contract: type: "date" is checked (ParaBun has no date arm, so it falls through to permissive — and date is what lockstep emits for every temporal column), and additionalProperties: false is enforced.

Notes

  • Pre-release (0.0.x-pre): the API may change before 0.1.0.
  • The extended/standard type split is still hand-maintained; it becomes automatic when gen-dts-rewrite lands the Phase-1 codegen.