mrkeyoor.com_
Wed 23 Sept 00:36 UTC
npmUtilsupdated 21 Sept 2026

@stoplight/yaml-ast-parser review

@stoplight/yaml-ast-parser 0.0.50 is a CommonJS fork of js-yaml that returns a position-bearing syntax tree instead of an ordinary JavaScript object. Maps contain mapping nodes, sequences contain item nodes, scalars retain raw text, and recovered parse errors are attached to the document. It also recognizes RAML `!include` references without loading their files. The current npm version was published in March 2024, yet it has no matching Git tag or release note; the only GitHub release is 0.0.45. Use it for existing Stoplight or RAML tooling that needs this exact AST, not as a fresh general-purpose YAML choice.

Verdict

@stoplight/yaml-ast-parser 0.0.50 installed in 1.4 seconds with 0 dependencies and 0 audit findings in our sandbox, but its browser bundle failed and its release has no matching Git tag or notes. Keep it for tooling already coupled to this recoverable RAML-aware AST; new YAML editors should start with `yaml`.

We installed it

Lab card: what happened when we installed @stoplight/yaml-ast-parserScreenshot of @stoplight/yaml-ast-parser documentation
Install✓ · 1.4s1 package on disk · 1 MB
ImportESM import works · require() works · CommonJS package
Browsern/acould not be bundled for the browser (Node-only code, most likely)
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does @stoplight/yaml-ast-parser install cleanly?

Yes. In a fresh container with an empty cache, npm install @stoplight/yaml-ast-parser finished in 1 seconds, leaving 1 package and 1 MB on disk. npm audit reported no known vulnerabilities.

Can @stoplight/yaml-ast-parser run in a browser?

Not directly: esbuild could not bundle it for the browser in our run, which normally means it depends on Node built-ins. Use it on the server, or find a browser-targeted alternative.

Does @stoplight/yaml-ast-parser work with both ESM and CommonJS?

Yes. Both import '@stoplight/yaml-ast-parser' and require('@stoplight/yaml-ast-parser') worked in Node 22 in our run. The package is published as CommonJS.

Does @stoplight/yaml-ast-parser include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

@stoplight/yaml-ast-parser or yaml: which should you use?

yaml: Use it for a maintained YAML 1.2 parser with document, CST, schema, comment, and stringification APIs. @stoplight/yaml-ast-parser 0.0.50 installed in 1.4 seconds with 0 dependencies and 0 audit findings in our sandbox, but its browser bundle failed and its release has no matching Git tag or notes.

When should you not use @stoplight/yaml-ast-parser?

You only need a JavaScript value from YAML. yaml and js-yaml have current documentation and avoid this package's custom tree traversal.

API stability2/5The `load`, `loadAll`, `Kind`, node interfaces, scalar helpers, and dump exports have stayed recognizable for years, which protects existing consumers. The package is still below 1.0 at version 0.0.50, its declaration exposes deprecated broad fields such as `value`, `key`, and `mappings`, and root nodes are typed with a parent even when no parent exists. A missing tag and changelog entry for the current npm artifact removes a useful way to audit compatibility.
Docs2/5The README identifies every node kind, lists the important fields on maps, mappings, sequences, scalars, and anchors, explains source ranges, describes error recovery, and mentions RAML includes and scalar inference. It provides only one load example. Loader options, diagnostic marks, comments, traversal, multi-document callbacks, ESM interop, dumping, include resolution, and browser support require inspection of old declarations, source, or generated tests.
Maintenance1/5Version 0.0.50 reached npm on March 4, 2024, but GitHub has no matching tag and lists only one release, 0.0.45 from 2020. The master branch's newest commit returned by the API is dated September 2019, while repository metadata reports a later 2024 push. The project is unarchived with 4 open issues and pull requests, yet its package scripts still name TypeScript 3.8, Mocha 3, Node 4-era types, and Travis CI.
Ecosystem3/5The npm endpoint counted 5,237,797 downloads in the latest completed week, despite GitHub showing only 3 stars. That gap points to heavy transitive use inside established Stoplight and API-description stacks rather than broad direct adoption. RAML include nodes and error-bearing source ranges remain useful in that niche. General YAML tools use different CST or document models, so switching away requires an adapter instead of a package-name replacement.

Use it if

  • An existing Stoplight, Spectral, or RAML workflow expects the package's numeric `Kind` enum and `YAMLNode` interfaces.
  • An editor or linter needs UTF-16 source offsets, comments, and recoverable diagnostics rather than a plain parsed value.
  • RAML `!include` tokens must appear as AST nodes so another layer can resolve them under its own path policy.
  • Code must inspect duplicate keys or malformed input while still receiving a partial syntax tree.
Skip it if

Setup reality

We installed @stoplight/yaml-ast-parser 0.0.50 in a fresh Node 22 Bookworm sandbox. npm took 1.4 seconds and left 1 package using 1 MB on disk. The package is 956 KB unpacked with 0 direct and 0 peer dependencies. npm audit reported 0 known vulnerabilities. It bundles TypeScript declarations.

The artifact is CommonJS with no exports map. Both require() and ESM import worked in our Node 22 checks. No credential, native compiler, or configuration file is needed. A browser bundle could not be built by esbuild in the measured environment, so do not assume the parser belongs in a client-side editor without testing your exact bundler and target.

load() returns a YAMLNode, not a plain object. Branch on Kind before reading mappings, items, or scalar values. The parser often recovers and places diagnostics in errors; receiving a root node does not establish that input is valid. Positions are offsets into the original JavaScript string, measured in UTF-16 code units. Convert carefully before patching a UTF-8 file buffer.

Comments are collected separately rather than attached to the mapping or item they describe. loadAll() reports each YAML document through a callback. RAML includes remain unresolved syntax. Version 0.0.50 ships generated tests and declarations built with an older toolchain, and the public README documents only the main node shapes. Budget time to read the declarations and tests before depending on loader options, dump behavior, or scalar inference in production.

Patterns

Load YAML and reject recovered errors parse-syntax-tree

import * as YAML from '@stoplight/yaml-ast-parser';

const source = 'name: demo\nenabled: true\n';
const root = YAML.load(source);
if (root.errors.length > 0) {
  throw new Error(root.errors.map(error => error.reason).join('; '));
}

Version 0.0.50 can return a tree after syntax recovery. An empty `errors` array is the check for a clean parse.

Check the node kind before reading a map narrow-node-kind

if (root.kind !== YAML.Kind.MAP) {
  throw new TypeError('expected a YAML map');
}
const mappings = (root as YAML.YamlMap).mappings;

Map, mapping-pair, sequence, scalar, anchor-reference, and include-reference nodes have different fields. Deprecated convenience fields are broadly typed.

Locate a named mapping entry find-map-value

const pair = (root as YAML.YamlMap).mappings.find(
  mapping => mapping.key.value === 'name',
);
if (pair?.value.kind === YAML.Kind.SCALAR) {
  console.log((pair.value as YAML.YAMLScalar).value);
}

A map stores `YAMLMapping` pairs. The mapping value is another node and still needs a kind check.

Traverse the six AST node kinds walk-all-nodes

function* walk(node: YAML.YAMLNode): Generator<YAML.YAMLNode> {
  yield node;
  if (node.kind === YAML.Kind.MAP) {
    for (const pair of (node as YAML.YamlMap).mappings) yield* walk(pair);
  } else if (node.kind === YAML.Kind.MAPPING) {
    yield* walk((node as YAML.YAMLMapping).key);
    yield* walk((node as YAML.YAMLMapping).value);
  } else if (node.kind === YAML.Kind.SEQ) {
    for (const item of (node as YAML.YAMLSequence).items) yield* walk(item);
  }
}

The public tree has no general `children()` method. Mapping pairs are nodes and must be visited if their ranges or errors matter.

Recover the exact text covered by a node slice-original-source

const original = source.slice(node.startPosition, node.endPosition);

Positions count UTF-16 code units in the JavaScript string. They are not UTF-8 byte offsets for a Buffer.

Turn parser marks into editor positions report-diagnostics

const diagnostics = root.errors.map(error => ({
  message: error.reason,
  severity: error.isWarning ? 'warning' : 'error',
  line: error.mark?.line ?? 0,
  column: error.mark?.column ?? 0,
}));

Mark line and column values are zero-based. Add 1 only at a UI boundary that displays one-based positions.

Collect every document in a YAML stream parse-document-stream

const documents: YAML.YAMLNode[] = [];
YAML.loadAll(source, document => documents.push(document));
for (const document of documents) {
  console.log(document.errors);
}

`loadAll()` uses a callback and returns void. Each document has its own root and error list.

Read document-level comment ranges inspect-comments

const document = YAML.safeLoad('name: demo # public label\n');
for (const comment of document.comments ?? []) {
  console.log(source.slice(comment.startPosition, comment.endPosition));
}

Comments are collected separately. The parser does not assign a comment to a particular key or sequence item.

Infer a scalar before converting it classify-scalar

const scalar = pair.value as YAML.YAMLScalar;
const scalarType = YAML.determineScalarType(scalar);
if (scalarType === YAML.ScalarType.int) {
  const value = YAML.parseYamlBigInteger(scalar.value);
}

Scalar text and inferred type are separate. Big integers may return a number or bigint depending on the value.

Keep duplicate-key diagnostics enabled detect-duplicate-keys

const document = YAML.load('name: first\nname: second\n');
const reasons = document.errors.map(error => error.reason);

Loader options can ignore duplicate keys, but downstream meaning stays ambiguous. Configuration and API descriptions should normally reject them.

Collect unresolved RAML include nodes find-raml-includes

const document = YAML.load('schema: !include schema.json\n');
const includes = [...walk(document)].filter(
  node => node.kind === YAML.Kind.INCLUDE_REF,
);

An `INCLUDE_REF` records source syntax only. Resolve it beneath an allowed root and detect recursive includes in application code.

Read an anchor reference and its resolved node inspect-anchor-reference

for (const node of walk(root)) {
  if (node.kind === YAML.Kind.ANCHOR_REF) {
    const ref = node as YAML.YAMLAnchorReference;
    console.log(ref.referencesAnchor, ref.value);
  }
}

Anchor references carry the anchor name and a node value. Preserve node ranges if diagnostics must point back to the alias token.

Alternatives

PackageRegistryPick it when
yamlnpmUse it for a maintained YAML 1.2 parser with document, CST, schema, comment, and stringification APIs.
js-yamlnpmUse it when the task is conventional YAML parsing and dumping rather than source-aware AST diagnostics.
yaml-ast-parsernpmUse the original unscoped package only when an old dependency requires that exact package name; it is older than the Stoplight fork.
@stoplight/spectral-corenpmUse Spectral's core when the actual goal is linting structured documents with rules and diagnostics, not maintaining a parser directly.

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.