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

@toomuchdesign/json-schema-fns

v0.7.0

Published

Immutable, type-safe utilities for transforming and composing JSON Schemas.

Readme

@toomuchdesign/json-schema-fns

Build Status Npm version Coveralls

@toomuchdesign/json-schema-fns is a type-safe immutable utility library for transforming JSON Schemas.

It ensures that schema transformations not only update the runtime schema correctly but also preserve accurate TypeScript type inference. This makes it especially useful when paired with tools like json-schema-to-ts.

import { omitProps } from '@toomuchdesign/json-schema-fns';
import type { FromSchema } from 'json-schema-to-ts';

const userSchema = {
  type: 'object',
  properties: {
    id: { type: 'string' },
    password: { type: 'string' },
  },
  required: ['id', 'password'],
} as const;

const publicUserSchema = omitProps(userSchema, ['password']);
type PublicUser = FromSchema<typeof publicUserSchema>;
// { id: string }

Why?

Manipulating JSON Schemas directly can be verbose and error-prone.

This library provides small, focused utilities that keep runtime schemas and TypeScript types in sync — especially when paired with json-schema-to-ts.

Installation

npm install @toomuchdesign/json-schema-fns

API

  • omitProps – Omit specific properties from an object JSON schema
  • pickProps – Pick only specific properties from an object JSON schema
  • mergeProps – Merge two object JSON schemas properties and patternProperties props into one. If the same property key exists in both schemas, the property from schema2 takes precedence
  • requireProps – Mark specific properties in a object JSON schema as required. If no keys provided, all properties become required
  • optionalProps – Make specific properties of a object JSON schema optional. If no keys provided, all properties become optional
  • sealSchemaDeep – Recursively set additionalProperties: false on all object JSON schema schemas
  • unsealSchemaDeep – Recursively remove additionalProperties and unevaluatedProperties keywords from all object JSON schema schemas

omitProps

Omit specific properties from an object JSON schema. Live demo ⚡

import { omitProps } from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  properties: {
    a: { type: 'string' },
    b: { type: 'number' },
  },
  required: ['a', 'b'],
} as const;

const result = omitProps(schema, ['b']);

pickProps

Pick only specific properties from an object JSON schema. Live demo ⚡

import { pickProps } from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  properties: {
    a: { type: 'string' },
    b: { type: 'number' },
  },
  required: ['a', 'b'],
} as const;

const result = pickProps(schema, ['b']);

mergeProps

Merge two object JSON schemas properties and patternProperties props into one. If the same property key exists in both schemas, the property from schema2 takes precedence. Live demo ⚡

import { mergeProps } from '@toomuchdesign/json-schema-fns';

const schema1 = {
  type: 'object',
  properties: {
    a: { type: 'string' },
  },
  required: ['a'],
} as const;

const schema2 = {
  type: 'object',
  properties: {
    b: { type: 'number' },
  },
  required: ['b'],
} as const;

const result = mergeProps(schema1, schema2);

requireProps

Mark specific properties in a object JSON schema as required. If no keys provided, all properties become required. Live demo ⚡

import { requireProps } from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  properties: {
    a: { type: 'string' },
    b: { type: 'string' },
    c: { type: 'string' },
  },
  required: ['b'],
} as const;

const result = requireProps(schema, ['a', 'c']);

optionalProps

Make specific properties of a object JSON schema optional. If no keys provided, all properties become optional. Live demo ⚡

import { optionalProps } from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  properties: {
    a: { type: 'string' },
    b: { type: 'string' },
    c: { type: 'string' },
  },
  required: ['a', 'b', 'c'],
} as const;

const result = optionalProps(schema, ['b', 'c']);

sealSchemaDeep

Recursively set additionalProperties: false on all object JSON schema schemas. Live demo ⚡

It does not modify JSON Schema combinators such as allOf, anyOf, oneOf, or not. This ensures that the logical combination of schemas remains intact and that the semantics of the schema are not altered in any way.

import { sealSchemaDeep } from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  required: ['name'],
  properties: {
    name: { type: 'string' },
    address: {
      type: 'object',
      properties: {
        street: { type: 'string' },
      },
    },
  },
} as const;

const result = sealSchemaDeep(schema);

unsealSchemaDeep

Recursively remove additionalProperties and unevaluatedProperties keywords from all object JSON schema schemas. Live demo ⚡

It does not modify JSON Schema combinators such as allOf, anyOf, oneOf, or not. This ensures that the logical combination of schemas remains intact and that the semantics of the schema are not altered in any way.

import { unsealSchemaDeep } from '@toomuchdesign/json-schema-fns';

const schema = {
  type: 'object',
  additionalProperties: false,
  required: ['name'],
  properties: {
    name: { type: 'string' },
    address: {
      type: 'object',
      additionalProperties: false,
      properties: {
        street: { type: 'string' },
      },
    },
  },
} as const;

const result = unsealSchemaDeep(schema);

Composition & pipe-friendly API (experimental)

In addition to the standard functional API, json-schema-fns also offers a composition-friendly counterpart that enables schema transformations through a pipeable interface. Live demo ⚡

Note: piping could lead TypeScript to hit its internal recursion limits producing the following error: TS2589: Type instantiation is excessively deep and possibly infinite

Note: the library does not include its own pipe utility. You are free to use any composition library you prefer, such as pipe-ts, ts-functional-pipe or even bigger libraries like effect or remeda. See composition tests.

import {
  pipeMergeProps,
  pipeOmitProps,
  pipeRequireProps,
  pipeSealSchemaDeep,
} from '@toomuchdesign/json-schema-fns';
import { pipeWith } from 'pipe-ts';

const schema = {
  type: 'object',
  properties: {
    a: { type: 'string' },
    b: { type: 'string' },
  },
  required: ['a'],
} as const;

const result = pipeWith(
  schema,
  pipeMergeProps({
    type: 'object',
    properties: {
      c: { type: 'string' },
    },
  }),
  pipeOmitProps(['a']),
  pipeRequireProps(['b']),
  pipeSealSchemaDeep(),
);

Related projects

  • https://github.com/codeperate/json-schema-builder
  • https://github.com/livelybone/union-tuple
  • https://github.com/ksxnodemodules/typescript-tuple

Todo

  • Replace type-fest's UnionToTuple type
  • Consider exposing a pipe utility

Dev notes

Types structure

The types exposed by this library are intentionally simplified to make them more explicit and easier to work with. Specifically, we unwrap generic types only at the top level—this means simplification is applied to non-recursive (non-deep) generics, and nested generic structures are left intact.

As a result, manual validation of output types is required before each release to ensure they match the expected structures. This step is important to prevent subtle type regressions that automated tests may not catch.

If anything in this process is unclear or if there's a better way to integrate type checking into our workflow, feel free to raise it—I'd appreciate any suggestions.

Contributing

Contributions are welcome! Before opening a PR, please run:

npx changeset