mrkeyoor.com_
Sat 19 Sept 23:47 UTC
npmUtilsupdated 18 Sept 2026

yaml review

yaml is a JavaScript parser, writer, and syntax-tree toolkit for YAML 1.1 and 1.2. parse and stringify cover plain data; parseDocument keeps comments, anchors, blank lines, directives, warnings, and errors for round-trip editing; Lexer, Parser, and Composer expose lower layers for formatters and language tools. Version 2.9.0 changes an important promise: parseDocument and parseAllDocuments are no longer documented as never throwing. The release fixes large-array push usage and a recursive lexer path, while acknowledging that malicious nesting may still trigger errors such as call-stack exhaustion.

181.2Mdownloads / wk
Verdict

Choose yaml when YAML fidelity matters, especially for comment-preserving edits or syntax tooling. For a small trusted config you may prefer a narrower parser, and hostile input needs size limits plus exception handling after the 2.9.0 guarantee change.

We installed it

Lab card: what happened when we installed yamlScreenshot of yaml documentation
Install✓ · 0.4s2 packages on disk · 2 MB
ImportESM import works · require() works · CommonJS package with exports map
Browser31.2 KBgzipped (101.5 KB minified), bundled with esbuild
Typesno TypeScript types found
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does yaml install cleanly?

Yes. In a fresh container with an empty cache, npm install yaml finished in 0.4s, leaving 2 packages and 2 MB on disk. npm audit reported no known vulnerabilities.

How much does yaml add to a browser bundle?

31.2 KB gzipped (101.5 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does yaml work with both ESM and CommonJS?

Yes. Both import 'yaml' and require('yaml') worked in Node 22 in our run. The package is published as CommonJS with an exports map.

Does yaml include TypeScript types?

No type declarations were found in our install, so TypeScript users need their own declarations.

yaml or js-yaml: which should you use?

js-yaml: Use it for established load and dump calls when comment-preserving document edits are unnecessary. Choose yaml when YAML fidelity matters, especially for comment-preserving edits or syntax tooling.

When should you not use yaml?

You only accept JSON-compatible configuration and control every producer; JSON.parse has no YAML schema, anchor, tag, or implicit-scalar ambiguity

API stability4/5The project says documented endpoints follow semantic versioning, and the v2 layers of parse/stringify, Document nodes, visitors, Lexer, Parser, and Composer remain available. Version 2.9.0 makes a documentation-level contract correction by withdrawing the claim that document parsing never throws. The registry also has a 3.0 prerelease on the next tag, so production lockfiles should stay on the stable major until its migration is chosen deliberately.
Docs5/5eemeli.org/yaml separates parse and stringify, Documents, content nodes, schemas and tags, aliases, errors, visitors, lexer/parser/composer internals, browser use, and the command-line tool. It explains YAML version choices and preserves code examples for both plain values and document edits. The 2.9.0 release note openly corrects the earlier never-throw claim, which is exactly the kind of boundary parser documentation should state.
Maintenance4/5GitHub reports 1,688 stars, an unarchived repository, a push on August 1, 2026, and 37 open issues and pull requests in the combined counter. Version 2.9.0 shipped May 11, 2026 with fixes for a large Array.prototype.push.apply call and recursive lexer call-stack exhaustion. A version 3 prerelease is published on the next tag. The project is active, though its repository scale suggests concentrated maintainer ownership.
Ecosystem5/5The npm downloads endpoint counted 193,382,837 downloads for the completed week ending August 22, 2026. The stable package has no direct or peer dependencies, exposes CommonJS and ESM-compatible loading in our Node 22 check, supports browsers, and covers both simple value parsing and source-preserving tooling. That reach makes it a common transitive parser, so applications should still own input limits rather than treating popularity as a security boundary.

Use it if

  • You must edit a YAML document and preserve comments, anchors, directives, and document structure when writing it back
  • A tool needs warnings and source-aware nodes rather than only the JavaScript value returned by parse
  • You support YAML 1.1 inputs or multi-document streams in addition to the default YAML 1.2 behavior
  • You are building a YAML linter, formatter, or editor integration and need lexer, parser, composer, or visitor APIs
Skip it if

Setup reality

Our clean Node 22 install of yaml 2.9.0 succeeded in 0.4 seconds. It left two packages using 2 MB, and npm audit found no known vulnerabilities. yaml declares no direct or peer dependencies; its own unpacked package is 1,372 KB. It is CommonJS with an exports map. require() and ESM import both worked in our sandbox. Our type check found no TypeScript types. A full esbuild browser import measured 101.5 KB minified and 31.2 KB gzipped.

No credentials or config files are needed. The first decision is schema and version. YAML 1.2 is the normal default; choose YAML 1.1 only for documents that rely on its older scalar resolution. parse returns a JavaScript value and is convenient for trusted files. parseDocument returns a Document with errors and warnings plus node metadata. Check doc.errors before using doc.toJS(), because partial recovery can produce a document object even when the source is invalid.

Round-trip editing needs the Document API. setIn and addIn can modify paths while retaining surrounding comments and node structure; converting to plain JavaScript and calling stringify builds a new document and loses that source-level information. Aliases can expand one anchored value many times, so keep alias expansion limits in place for untrusted files. Custom tags execute construction logic and should come from application-owned code, never from data-selected modules.

In 2.9.0, parsing APIs may still throw on malicious or pathological input despite error collection. Put a byte limit before parsing, catch exceptions, and consider worker or request time limits at an untrusted boundary. The parser is synchronous, so a large document occupies the event loop until it finishes. For multi-document input, parseAllDocuments returns every document at once; process size and document count limits outside the library when the source is not trusted.

Patterns

Parse a YAML config value parse-config

import {parse} from 'yaml';

const config = parse(source);

parse uses YAML 1.2 behavior by default. Catch exceptions when the source is untrusted.

Write a JavaScript value as YAML stringify-data

import {stringify} from 'yaml';

const output = stringify({
  service: 'api',
  replicas: 3,
});

stringify creates a new document. It cannot preserve comments from an earlier parsed string.

Check a document before conversion inspect-parse-errors

import {parseDocument} from 'yaml';

const doc = parseDocument(source);
if (doc.errors.length > 0) {
  throw new AggregateError(doc.errors, 'invalid YAML');
}
const value = doc.toJS();

Version 2.9.0 no longer promises parseDocument will never throw, so wrap the call as well at hostile-input boundaries.

Edit a document without discarding comments preserve-comments

const doc = parseDocument(source);
doc.setIn(['database', 'poolSize'], 12);
const updated = String(doc);

Keep the Document object. Converting to plain JavaScript and stringifying again loses source comments and layout choices.

Read a path from a document read-nested-value

const doc = parseDocument(source);
const port = doc.getIn(['server', 'port']);

Document path methods operate on YAML nodes and values without converting the entire document first.

Append an item to a nested sequence add-sequence-item

const doc = parseDocument(source);
doc.addIn(['services'], {name: 'worker', replicas: 2});

addIn expects the target path to contain a collection suitable for the new item.

Read a multi-document stream parse-document-stream

import {parseAllDocuments} from 'yaml';

const documents = parseAllDocuments(source);
for (const doc of documents) {
  if (doc.errors.length) throw new AggregateError(doc.errors);
  consume(doc.toJS());
}

All documents are returned together. Apply source-size and document-count limits before parsing untrusted streams.

Opt into YAML 1.1 scalar rules use-yaml-1-1

import {parse} from 'yaml';

const legacy = parse('enabled: yes', {version: '1.1'});

Under the default YAML 1.2 schema, yes is normally a string rather than a boolean.

Visit and edit scalar nodes visit-scalars

import {parseDocument, visit} from 'yaml';

const doc = parseDocument(source);
visit(doc, {
  Scalar(_key, node) {
    if (node.value === 'staging') node.value = 'production';
  },
});

Visitors operate on YAML nodes, so edits can retain comments and collection structure.

Create an anchor and alias create-alias

import {Document} from 'yaml';

const doc = new Document({defaults: {retries: 3}});
const defaults = doc.get('defaults', true);
doc.set('worker', doc.createAlias(defaults, 'defaults'));

Aliases reference an anchored node. Confirm the produced structure and keep expansion limits for inputs you do not control.

Read low-level parser tokens parse-cst-tokens

import {Parser} from 'yaml';

for (const token of new Parser().parse(source)) {
  inspectToken(token);
}

The Parser layer is for syntax tooling. Application config readers should stay with parse or parseDocument.

Validate parsed data separately validate-application-shape

import {parse} from 'yaml';
import {z} from 'zod';

const schema = z.object({
  port: z.number().int().min(1).max(65535),
});
const config = schema.parse(parse(source));

Valid YAML can still violate the application's required keys, types, and ranges.

Alternatives

PackageRegistryPick it when
js-yamlnpmUse it for established load and dump calls when comment-preserving document edits are unnecessary
yaml-ast-parsernpmUse it only when maintaining older tooling already built around that package's AST shape
gray-matternpmUse it when the actual job is extracting and parsing front matter from Markdown files
smol-tomlnpmUse TOML when you control the config format and want fewer implicit scalar and tag rules

More utils guides

lru-cache · type-fest · ajv · 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.