mrkeyoor.com_
Sat 08 Aug 21:01 UTC
npmUtilsupdated 08 Aug 2026

oas-schema-walker

oas-schema-walker is a tiny CommonJS helper that visits an OpenAPI 3 schema object and calls your callback for the root and recognized nested schemas. It descends through items, properties, patternProperties, additional properties or items, allOf, anyOf, oneOf, and not while tracking depth and repeated object references. It does not parse an OpenAPI document, resolve $ref targets, validate schemas, or walk paths and operations; you must first select the Schema Object you want to inspect.

Verdict

This is a compact fit for legacy oas-kit code that walks known OpenAPI 3.0 schema shapes. For new tooling, its missing 3.1 keywords, absent ref resolution, stale release, and undocumented state quirks make a broader parser or JSON Schema walker the safer install.

API stability4/5The package exports only getDefaultState and walkSchema, and version 1.1.5 has remained unchanged since July 2020. That tiny surface is easy to keep compatible. Several subtle behaviors are therefore stable too: callbacks happen before seen-object checks, $ref nodes are replaced for callback purposes, state.property is mutable and relative, and combine does not clearly rewrite the parent link.
Docs2/5The package README lists the two functions and callback concept, and the oas-kit site provides wider project context. It does not show a complete runnable example or document recognized keywords, traversal order, $ref truncation, cycle callback behavior, state fields, or combine and allowRefSiblings. Understanding safe use requires reading the short index.js implementation directly.
Maintenance2/5The oas-kit repository is not archived and carries 747 stars, but its last push was in October 2023 and oas-schema-walker 1.1.5 was published in July 2020. The package's own test script is the npm placeholder that exits unsuccessfully. GitHub reports 45 open issues and pull requests across the entire monorepo, not specifically this walker.
Ecosystem3/5The package recorded 4,387,690 downloads for the measured week and sits inside the established oas-kit family alongside swagger2openapi, oas-validator, oas-resolver, and reftools. Its direct ecosystem is still narrow: there are no plugins, types, resolver hooks, or framework adapters, and its download volume is likely driven mainly by transitive use in OpenAPI toolchains.

Use it if

  • You already use the Mermade oas-kit packages and need the same schema traversal behavior they expect
  • A CommonJS script needs a dependency-free pre-order walk over OpenAPI 3.0 schema composition and property keywords
  • You need to inspect or mutate schema nodes in place through a callback and can control the input shape
  • Repeated JavaScript object references or cycles are possible and a WeakMap-based stop condition is sufficient
Skip it if

Setup reality

npm install oas-schema-walker adds no runtime dependencies, native build, peer dependency, credential, or config file. Import getDefaultState and walkSchema with require(), then call walkSchema(schema, parent, state, callback). The README's generated signature is confusing, but the source order is schema first, then parent, state, and callback; use {} as the root parent and getDefaultState() for state. Passing an object without depth also triggers default initialization. The callback runs before cycle detection, so a repeated object reference is reported once more when encountered but is not descended again. state is one mutable object shared across the entire traversal: depth is useful, top becomes false after the root and is not restored, and property records the most recently selected child such as properties/name rather than a durable full path. Copy any path information inside the callback instead of retaining state by reference. $ref nodes are special: the callback receives a new minimal object, not the original node, and all siblings are discarded unless allowRefSiblings keeps description. combine can flatten a single-entry allOf, anyOf, or oneOf into the node presented to the callback, but because the implementation reassigns a local variable, do not assume the parent's original child was replaced. For transformations, clone the document first if callers still need the original, and write tests for every schema keyword your documents use.

Patterns

Visit every recognized schema nodewalk-schema

const { getDefaultState, walkSchema } = require('oas-schema-walker');

walkSchema(schema, {}, getDefaultState(), (node, parent, state) => {
  console.log(state.depth, node.type);
});

The argument order is schema, parent, state, callback. The generated README signature is easy to misread.

Collect nodes reached through propertiescollect-property-nodes

const properties = [];

walkSchema(schema, {}, getDefaultState(), (node, parent, state) => {
  if (state.property && state.property.startsWith('properties/')) {
    properties.push({ name: state.property.slice(11), node });
  }
});

state.property is only the latest relative edge, not a complete JSON Pointer, and the same state object is reused. Copy values immediately.

Count visited schema nodescount-schema-nodes

let count = 0;
walkSchema(schema, {}, getDefaultState(), () => {
  count += 1;
});
console.log(count);

A repeated object reference still triggers the callback on its repeated encounter because the seen check happens after callback.

Collect required names from object schemascollect-required-fields

const required = new Set();

walkSchema(schema, {}, getDefaultState(), (node) => {
  for (const name of node.required || []) required.add(name);
});

The set merges names from every nesting level. Track your own path if identical property names in different objects must stay separate.

Find deprecated schema nodesfind-deprecated-nodes

const deprecated = [];

walkSchema(schema, {}, getDefaultState(), (node, parent, state) => {
  if (node.deprecated === true) {
    deprecated.push({ edge: state.property, node });
  }
});

Store a copied edge or path, not state itself, because later traversal mutates the shared state object.

Mutate ordinary schema nodes in placeadd-missing-descriptions

walkSchema(schema, {}, getDefaultState(), (node) => {
  if (!node.description && node.type) {
    node.description = `A ${node.type} value`;
  }
});

Callbacks receive original objects for ordinary nodes, so mutations persist. Clone schema first when mutation must not affect the caller.

Collect reference stringsdetect-ref-nodes

const refs = [];

walkSchema(schema, {}, getDefaultState(), (node) => {
  if (node.$ref) refs.push(node.$ref);
});

The walker does not resolve refs. The callback receives a new minimal object and traversal stops at that ref.

Preserve descriptions beside refskeep-ref-descriptions

const state = getDefaultState();
state.allowRefSiblings = true;

walkSchema(schema, {}, state, (node) => {
  if (node.$ref) console.log(node.$ref, node.description);
});

Only description is retained as a ref sibling. Other siblings are dropped from the temporary callback node and are not traversed.

Flatten single-entry composition for inspectioncombine-single-branch

const state = getDefaultState();
state.combine = true;

walkSchema(schema, {}, state, (node) => {
  console.log(node.type, node.allOf);
});

combine affects single-entry allOf, anyOf, and oneOf. Treat it as a callback view, because the locally replaced object may not replace its parent's child reference.

Inspect only shallow nodeslimit-by-depth

walkSchema(schema, {}, getDefaultState(), (node, parent, state) => {
  if (state.depth <= 2) {
    console.log(state.depth, state.property);
  }
});

This filters callback work only; the walker still descends through every recognized child because callbacks cannot prune traversal.

Select schemas from an OpenAPI documentwalk-component-schema

for (const [name, schema] of Object.entries(api.components?.schemas || {})) {
  walkSchema(schema, {}, getDefaultState(), (node) => {
    console.log(name, node.type);
  });
}

oas-schema-walker does not find component schemas for you. Select each Schema Object from the OpenAPI document first.

Detect keywords the walker will not descendguard-unsupported-keywords

const unsupported = ['prefixItems', 'contains', 'if', 'then', 'else', 'dependentSchemas'];

walkSchema(schema, {}, getDefaultState(), (node) => {
  for (const key of unsupported) {
    if (key in node) console.warn(`Manual traversal needed for ${key}`);
  }
});

OpenAPI 3.1 uses the JSON Schema 2020-12 vocabulary, which is broader than this walker's hard-coded child list.

Alternatives

PackageRegistryPick it when
json-schema-traversenpmYou need a focused JSON Schema walker with callback paths and broader keyword handling
@apidevtools/swagger-parsernpmYou need to parse, validate, bundle, and dereference complete Swagger or OpenAPI documents
@apidevtools/json-schema-ref-parsernpmResolving and bundling local or remote $ref targets is the central requirement
@readme/openapi-parsernpmYou want a maintained parser and validator aimed at complete modern OpenAPI documents