json-schema-merge-allof
Safely merge allOf subschemas into a single, readable JSON Schema without changing validation.
Repository Health
Technical Analysis
json-schema-merge-allof collapses the allOf keyword in a JSON Schema, folding every combined subschema into a single composed schema that is far easier to read, inspect, and reason about. Unlike naive object-merge approaches, it performs a real logical intersection of validation keywords, raising minimums, lowering maximums, intersecting type sets, and unioning required lists, so the merged result validates exactly the same set of documents as the original.
It understands the interdependent keywords that trip up simpler mergers, treating properties, patternProperties and additionalProperties (and items with additionalItems) as a single unit, and throws when subschemas have no logical intersection. Pluggable resolvers let you override how any keyword, including meta keywords like title and description, is combined.
What You Get
- A single function that strips allOf from anywhere in a schema and folds the constraints into a readable composed schema
- Lossless merging that preserves validation semantics, so the result never accepts or rejects more than the original
- Correct handling of interdependent keywords (properties/patternProperties/additionalProperties and items/additionalItems)
- Pluggable keyword resolvers and a default resolver hook to customise how conflicting values are combined
- Options like ignoreAdditionalProperties and deep to control merge behaviour, plus clear errors on impossible intersections
Common Use Cases
- Simplifying machine-generated or heavily composed schemas so humans and tooling can read them
- Preprocessing schemas before feeding them to generators (forms, types, docs) that don’t understand allOf
- Flattening shared base schemas that are extended via allOf into concrete standalone schemas
- Detecting logically impossible schema combinations early by catching the thrown intersection error
Under The Hood
Architecture - The library centers on src/index.js, which walks a JSON Schema, gathers every allOf subschema alongside the parent, and per-keyword computes a merged value by intersecting or unioning the conflicting values (highest minimum, lowest maximum, intersected type sets, unioned required). Interdependent keywords are delegated to complex resolvers in src/complex-resolvers/properties.js and items.js, which treat properties/patternProperties/additionalProperties and items/additionalItems as coupled units so their combined semantics stay correct. Shared helpers live in src/common.js.
Tech Stack - Plain JavaScript (Node >= 12) with three runtime dependencies: lodash for data manipulation, compute-lcm for numeric multipleOf resolution, and json-schema-compare for schema equality checks. Tests run on Vitest with Ajv used as an independent validator to confirm equivalence, plus chai and sinon.
Code Quality - The repo has a thorough test suite under test/specs covering validation equivalence, properties, items, custom resolvers, meta-schema handling, stripping, and extraction, with coverage tracked via c8/coveralls. ESLint and Prettier are enforced (pretest runs eslint). The design is modular and the resolver abstraction keeps per-keyword logic isolated and testable.
API Design - The public surface is a single mergeAllOf(schema, options) call, which keeps the common case trivial while the options object (resolvers, deep, ignoreAdditionalProperties) exposes deep customisation for advanced users. The README documents the resolver contract, combined resolvers, and default resolver clearly, making the extension model approachable.