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

@stoplight/yaml

@stoplight/yaml is a YAML parser and source-location toolkit built for editors, linters, and API-document tooling. It can return ordinary JavaScript data together with an abstract syntax tree, line offsets, diagnostics, and attached comments, then translate between zero-based line and character positions and JSON paths. It also handles anchors, optional merge keys, large integers, key-order metadata, and YAML serialization. If all you need is config-file parsing, most of that machinery is unnecessary.

Verdict

A specialized choice for tooling that must connect YAML text, JSON paths, ranges, and diagnostics. For ordinary configuration loading, use yaml or js-yaml and avoid the older CommonJS packaging and Stoplight-specific result model.

API stability4/5The public surface is compact and version 4.3.0 still centers on parse, parseWithPointers, location conversion, safeStringify, AST types, and a few order and anchor helpers. Type declarations make the result shape explicit. The less stable part is behavioral rather than syntactic: option normalization changes duplicate-key handling depending on whether options are omitted or supplied.
Docs3/5The README gives working examples for the three headline functions and links generated TSDoc plus releases. The declarations clearly list parse options and result types. Important production details remain in source rather than prose, including default json mode, bigint conversion, disabled merge keys and comments, the explicit-options duplicate behavior, safeStringify's string pass-through, and trapAccess usage.
Maintenance3/5The repository is not archived and was pushed in April 2025, but npm version 4.3.0 dates to March 2024. GitHub reports 20 open issues and pull requests together, compared with only 14 stars, and the package still declares a Node 10-era floor and CommonJS-only entry. It appears maintained as Stoplight infrastructure, with limited standalone momentum.
Ecosystem4/5The npm endpoint reports 4,881,736 downloads for the measured week, driven largely by Stoplight's API design and linting toolchain. Its types and diagnostic locations align directly with @stoplight/types, and the AST parser is published separately. Outside that family, yaml and js-yaml have broader mindshare, so interoperability is strongest when a project already uses Stoplight packages.

Use it if

  • You are building a YAML-aware editor, linter, language service, or API specification tool that must map data paths back to source ranges
  • You need parsing errors as structured diagnostics with severity and zero-based ranges rather than only thrown strings
  • You need the parsed data and the full YAML AST from one operation
  • You work inside the Stoplight ecosystem and want the same @stoplight/types locations, diagnostics, and path segments used by its other packages
Skip it if

Setup reality

Install @stoplight/yaml with npm or yarn. Version 4.3.0 declares Node >=10.8, ships declarations, has no peer dependencies, and depends on tslib, @stoplight/types, @stoplight/yaml-ast-parser, and @stoplight/ordered-object-literal. Its package entry is CommonJS, so strict ESM projects rely on Node or bundler interop. parse() is only a convenience wrapper around parseWithPointers().data; the generic type parameter is a TypeScript assertion, not runtime schema validation. For editor work, keep the full parse result because lineMap, ast, diagnostics, metadata, and comments drive the location helpers. Line and character inputs are zero-based. Defaults are easy to misread: parsing is JSON-compatible by default, mergeKeys, bigInt, comment attachment, and key-order preservation are off. Large YAML integers are converted from bigint to Number unless bigInt: true, which can lose precision. Merge aliases are not folded into objects unless mergeKeys: true. Comments are not collected unless attachComments: true. preserveKeyOrder uses a symbol-backed ordered-object wrapper; use trapAccess() when consumers need reflection to follow that stored order. Duplicate-key behavior has an awkward edge: with no options it becomes a diagnostic in JSON mode, but the normalization of an explicit options object changes ignoreDuplicateKeys defaults, and json: false throws for repeated YAML mapping keys. safeStringify returns string inputs unchanged rather than quoting them as YAML scalars. Treat untrusted input as data only and add your own size limits and runtime schema validation.

Patterns

Parse YAML into JavaScript dataparse-yaml-data

import { parse } from '@stoplight/yaml';

const config = parse<{ port: number; debug: boolean }>(`
port: 8080
debug: false
`);
console.log(config.port);

The generic controls only the compile-time return type; validate unknown input with a runtime schema before trusting it.

Collect data, AST, and diagnosticsparse-with-diagnostics

import { parseWithPointers } from '@stoplight/yaml';

const result = parseWithPointers('server:
  port: [8080');
for (const diagnostic of result.diagnostics) {
  console.error(diagnostic.message, diagnostic.range.start);
}
console.log(result.data, result.ast, result.lineMap);

Many syntax problems are returned as diagnostics, but duplicate keys in YAML mode can throw, so boundary code should still catch exceptions.

Find the JSON path under a cursormap-position-to-path

const source = 'server:
  port: 8080
';
const result = parseWithPointers(source);
const path = getJsonPathForPosition(result, { line: 1, character: 8 });
console.log(path); // ['server', 'port']

Both line and character are zero-based, matching editor protocols rather than human line numbers.

Find the source range for a data pathmap-path-to-location

const location = getLocationForJsonPath(result, ['server', 'port']);
if (location) {
  console.log(location.range.start, location.range.end);
}

Keep the parser result that belongs to the exact source text; locations are derived from its AST and line map.

Keep large YAML integers as bigintpreserve-big-integers

const result = parseWithPointers<{ id: bigint }>(
  'id: 9007199254740993',
  { bigInt: true },
);
console.log(result.data?.id === 9007199254740993n);

bigInt defaults to false, which converts parsed bigint values to Number and can lose precision beyond the safe integer range.

Apply YAML merge keysresolve-merge-keys

const source = `
defaults: &defaults
  retries: 3
service:
  <<: *defaults
  name: api
`;
const result = parseWithPointers<{ service: { retries: number } }>(
  source,
  { mergeKeys: true },
);
console.log(result.data?.service.retries);

mergeKeys is false by default; without the option, << is retained as an ordinary mapping key.

Capture YAML comments by pointerattach-comments

const result = parseWithPointers(
  '# service settings
name: api # public name
',
  { attachComments: true },
);
console.log(result.comments);

Comments are stored separately by pointer with placements such as leading, trailing, before-eol, or between; they are not inserted into data.

Retain explicit mapping orderpreserve-key-order

import { parseWithPointers, trapAccess } from '@stoplight/yaml';

const result = parseWithPointers<Record<string, number>>(
  'third: 3
first: 1
second: 2',
  { preserveKeyOrder: true },
);
if (result.data) {
  const ordered = trapAccess(result.data);
  console.log(Reflect.ownKeys(ordered));
}

Order is kept in symbol-backed metadata. trapAccess() changes the ownKeys reflection result; it does not deep-wrap nested mappings.

Report JSON-incompatible YAML constructsenforce-json-compatible-yaml

const result = parseWithPointers('1: one
name: api', {
  json: true,
  ignoreDuplicateKeys: false,
});
console.log(result.diagnostics.map(item => item.message));

JSON mode expects string scalar keys. Set ignoreDuplicateKeys explicitly because providing an options object otherwise changes its normalized default.

Serialize an object as YAMLstringify-object

import { safeStringify } from '@stoplight/yaml';

const output = safeStringify(
  { server: { port: 8080 }, features: ['search', 'billing'] },
  { indent: 2, noRefs: true },
);
console.log(output);

Options are passed to the underlying AST parser's safeDump; aliases may be emitted unless noRefs is enabled.

Handle an already serialized stringstringify-string-input

const source = 'name: api
';
const output = safeStringify(source);
console.log(output === source); // true

safeStringify returns any string unchanged. It does not quote or escape a string as a YAML scalar.

Build a path directly from an AST nodebuild-node-path

import { buildJsonPath, Kind, parseWithPointers } from '@stoplight/yaml';

const result = parseWithPointers('items:
  - name: first');
if (result.ast?.kind === Kind.MAP) {
  const value = result.ast.mappings[0].value;
  if (value) console.log(buildJsonPath(value));
}

AST unions are discriminated by Kind; narrow the node before accessing mappings, items, key, or value fields.

Alternatives

PackageRegistryPick it when
yamlnpmChoose it for a modern YAML 1.2 parser with document editing, CST access, aliases, comments, and ESM-friendly packaging
js-yamlnpmChoose it for widely used parse and dump functions when source-to-path mapping is not required
@stoplight/yaml-ast-parsernpmChoose the lower-level dependency when you need direct AST control and can build diagnostics and path mapping yourself