mrkeyoor.com_
Sun 20 Sept 05:55 UTC
npmUtilsupdated 20 Sept 2026

js-yaml review

js-yaml parses YAML text into JavaScript values and serializes JavaScript values back to YAML. The default loader follows a YAML 1.2 core schema, while an explicit YAML 1.1 schema restores timestamps and older tag behavior. Version 5 rewrote the parser in TypeScript, added event and AST layers, passed the YAML test suite, bundled declarations, and replaced the old Type and Schema.extend APIs. Version 5.3 adds new documentation, exports DUMP_SCHEMA and YAMLException.throwAt(), groups parser constants, requires identify on custom tags, and fixes merge-key validation and literal << handling.

214.5Mdownloads / wk
Verdict

js-yaml is a good fit for parsing or generating YAML as data, and version 5.3 has much clearer schema and tag machinery. Use another parser for comment-preserving edits, and set hard limits plus an explicit schema for untrusted configuration.

We installed it

Lab card: what happened when we installed js-yamlScreenshot of js-yaml documentation
Install✓ · 0.3s2 packages on disk · 2 MB
ImportESM import works · require() works · CommonJS package with exports map
Browser17.1 KBgzipped (56.7 KB minified), bundled with esbuild
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does js-yaml install cleanly?

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

How much does js-yaml add to a browser bundle?

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

Does js-yaml work with both ESM and CommonJS?

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

Does js-yaml include TypeScript types?

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

js-yaml or yaml: which should you use?

yaml: Choose it for a document model that can retain comments and formatting during edits. js-yaml is a good fit for parsing or generating YAML as data, and version 5.3 has much clearer schema and tag machinery.

When should you not use js-yaml?

You must edit a document while preserving comments, anchors, scalar style, blank lines, and key order exactly; load and dump create a new representation

API stability3/5load, loadAll, and dump remain the everyday API, but version 5 is a substantial break from version 4 for schemas, tags, imports, empty input, browser paths, and formatting options. Version 5.3 also deprecates flat parser constants and makes identify mandatory for custom tags. Straight parsing migrates quickly; tools extending representation or importing internals need deliberate porting.
Docs5/5Version 5.3 explicitly ships a new documentation set, and the site now covers loaders, dumpers, schemas, tags, AST and event APIs, errors, and options. The repository has a detailed version 4 migration guide and a chronological changelog that calls out security limits and breaking behavior. Advanced tag and presenter work still demands careful reading because small schema choices change JavaScript types.
Maintenance5/5GitHub shows an unarchived repository pushed on August 21, 2026, with nine open issues and pull requests. Version 5.3.0 shipped August 14 after several security and correctness patches in the 5.2 line, including exponential parse behavior, merge-key limits, prototype fallback, timestamps, and flow scalar quoting. The project also maintains older lines when a fix needs backporting.
Ecosystem5/5The npm API counted 291,799,523 downloads in the latest completed week, and GitHub reports 6,626 stars. Configuration readers, linters, documentation tools, and frontmatter packages commonly depend on js-yaml. It includes declarations and works through CommonJS and ESM imports in our check. That reach means old version 4 examples remain common, so ecosystem volume does not guarantee current syntax.

Use it if

  • A Node tool needs plain objects from YAML configuration or needs to emit YAML without preserving the original layout
  • Untrusted input needs explicit alias, depth, and merge-key work limits before it is accepted
  • The application must opt between YAML 1.2 core values and documented YAML 1.1 tags
  • Custom scalar, sequence, or mapping tags should convert domain values through a schema
Skip it if

Setup reality

Our fresh Node 22 install of js-yaml 5.3.0 succeeded in 0.3 seconds. Two packages used 2 MB on disk, and npm audit reported no known vulnerabilities. The package itself has one direct dependency, no peers, is 1,560 KB unpacked, uses the MIT license, and includes TypeScript declarations. It is CommonJS with an exports map; both require() and ESM import worked. A whole-package browser import produced 56.7 KB minified and 17.1 KB gzipped.

Version 5 uses named exports. Import load and dump directly, or use a namespace import; code expecting a default export should be changed. Browser builds live under the documented browser export. Type declarations are included, so remove @types/js-yaml when it conflicts with the package definitions. load() now rejects empty input, while loadAll() returns an array for a document stream. Invalid YAML throws YAMLException with source marks; supply filename in options so multi-file tools report the right path.

The default CORE_SCHEMA does not resolve << as a merge key and does not convert timestamp text into Date. Add mergeTag to a schema for merges or select YAML11_SCHEMA for older tags. These choices change returned JavaScript types and should be fixed in application code rather than inferred from a file. Version 5.3 requires identify on every custom tag definition. A load-only tag can use identify: () => false. DUMP_SCHEMA now exposes the dumper's default representation choices.

Parsing YAML is resource-sensitive. Set maxAliases, maxDepth, and maxTotalMergeKeys for input outside your control. maxAliases can be zero when aliases are unnecessary. Duplicate keys reject by default; json: true makes the last value win, which can hide configuration mistakes. Custom tag resolvers execute your code during parsing, so do not register constructors that perform I/O or accept unsafe values. dump() cannot restore comments or original quoting because ordinary JavaScript objects do not retain them.

Patterns

Load a configuration file parse-yaml-file

import { load, YAMLException } from 'js-yaml';
import { readFileSync } from 'node:fs';

try {
  const config = load(readFileSync('app.yml', 'utf8'), {
    filename: 'app.yml',
  });
  console.log(config);
} catch (error) {
  if (error instanceof YAMLException) console.error(error.message);
  else throw error;
}

Version 5 load throws on an empty string. filename improves the marked error message.

Read several YAML documents parse-document-stream

import { loadAll } from 'js-yaml';

const documents = loadAll(`
name: first
---
name: second
`);

console.log(documents.length);

Use loadAll for streams separated by document markers. The older iterator signature is deprecated.

Dump sorted configuration serialize-yaml

import { dump } from 'js-yaml';

const text = dump(
  { ports: [443, 80], service: 'api' },
  { indent: 2, sortKeys: true, lineWidth: -1 },
);

lineWidth: -1 prevents automatic folding of long scalar lines. The output is newly formatted.

Opt into YAML merge behavior enable-merge-key

import { CORE_SCHEMA, load, mergeTag } from 'js-yaml';

const schema = CORE_SCHEMA.withTags(mergeTag);
const value = load(source, {
  schema,
  maxTotalMergeKeys: 1_000,
});

Merge keys are absent from the default CORE_SCHEMA. Bound total merged keys for untrusted documents.

Select legacy YAML 1.1 tags parse-yaml-1-1

import { load, YAML11_SCHEMA } from 'js-yaml';

const value = load('created: 2026-08-22', {
  schema: YAML11_SCHEMA,
});

console.log(value.created instanceof Date);

The default YAML 1.2 core schema leaves the timestamp as a string. YAML11_SCHEMA changes more than dates, so test the whole input set.

Limit aliases and nesting bound-parser-work

const value = load(untrustedText, {
  maxAliases: 0,
  maxDepth: 30,
  maxTotalMergeKeys: 500,
});

maxAliases: 0 rejects aliases. Pick limits from the configuration shape your application actually accepts.

Keep duplicate mappings as errors reject-duplicate-keys

load('mode: safe\nmode: unsafe'); // throws

const compatible = load('mode: safe\nmode: unsafe', {
  json: true,
});
console.log(compatible.mode); // unsafe

json: true keeps the last value. Avoid it for security or deployment configuration where duplicates should fail review.

Convert a tagged scalar define-custom-tag

import { CORE_SCHEMA, defineScalarTag, load } from 'js-yaml';

const urlTag = defineScalarTag('!url', {
  resolve: (source) => new URL(source),
  identify: (value) => value instanceof URL,
  represent: (value) => value.href,
});

const schema = CORE_SCHEMA.withTags(urlTag);
const config = load('endpoint: !url https://example.com/', { schema });

Version 5.3 requires identify. Validate source inside resolve before constructing domain values.

Create a tag that is never dumped define-load-only-tag

const envTag = defineScalarTag('!env', {
  resolve: (name) => process.env[name],
  identify: () => false,
});

const schema = CORE_SCHEMA.withTags(envTag);

identify: () => false is the version 5.3 pattern for load-only tags. Reading environment variables makes parsing context-dependent.

Import from CommonJS load-with-commonjs

const { load, dump } = require('js-yaml');

const data = load('enabled: true');
console.log(dump(data));

The measured package supports require(). ESM code should use named or namespace imports instead of assuming a default export.

Alternatives

PackageRegistryPick it when
yamlnpmChoose it for a document model that can retain comments and formatting during edits
yamljsnpmChoose it only for compatibility with an existing YAMLJS codebase after checking its slower maintenance pace
json5npmChoose it when human-edited configuration only needs comments, trailing commas, and relaxed JSON syntax

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · zod · 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.