Skip to content

Proposal: built-in YAML support, public API and placement #67347

Open

Description

@marcopiraccini

What is the problem this feature will solve?

An application that reads a YAML config file needs a third-party parser. Should Node provide one directly? If so, should it live in its own module?

YAML also came up in #53787, the discussion about Node's own configuration file.

What is the feature you are proposing to solve the problem?

#67157 proposes one function behind --experimental-yaml:

import { parse } from 'node:yaml';

parse('port: 8080'); // { port: 8080 }

Whether the parser is written in JS, vendored from yaml or js-yaml, or built in C++ or wasm is discussed in the PR, with measurements; the API is the same in every case. This issue is about the API.

  • parse(input[, options]) accepts a string or UTF-8 bytes in an ArrayBuffer, SharedArrayBuffer, typed array or DataView.
  • One document returns its value, multiple documents return an array, and an empty stream returns null.
  • Invalid YAML throws a SyntaxError with code ERR_INVALID_YAML and a line and column. With throwIfInvalid: false, it returns undefined instead.
  • The parser uses the YAML 1.2 core schema: yes and no are strings, and 0777 is decimal. It doesn't convert timestamps to dates, expand merge keys or decode !!binary.
  • Mappings become plain objects. Even __proto__ is an own property. Duplicate keys are errors. Aliases to a collection refer to the same object, so the result can contain cycles.

Possible follow-ups:

  • stringify(value[, replacer[, space]]), with arguments like JSON.stringify().
  • A version option. Should we reserve it now with '1.2' as the only supported value, or wait until there's a second version to choose from?
  • A reviver option to transform parsed values. We'd need to define how it visits shared references and cycles.
  • A file or stream API that can parse large inputs without keeping the whole source in memory.

I'd favor node:yaml if we expect to offer both parsing and stringifying. It keeps those operations together. One concern raised in review is whether that sets a precedent for a module per format. I'd judge TOML, XML and other formats on their own use cases.

What alternatives have you considered?

  1. Add util.parseYAML() alongside util.parseEnv(). This seems like a good fit if parsing is all we want.
  2. Use a shared module such as node:serdes, with serdes.yaml.parse(). Other formats could use it later, but we'd be designing the shared API with only one format in mind.
  3. Keep YAML internal if Node adopts it for a feature such as config files or import config from './config.yaml' with { type: 'yaml' }. Applications would still choose their own parser.
  4. Leave YAML to packages such as yaml and js-yaml. Users can already choose between them, and core wouldn't take on another parser to maintain.

Activity

  1. marcopiraccini commented on Nov 8, 2026

    @marcopiraccini
    ContributorAuthor

    Done this as base for the discussion started here: #67157 (comment)

  2. panva commented on Nov 8, 2026

    @panva
    Member

    Is there a good reason for going core straight away? Can this not follow the path of node:logger (https://github.com/nodejs/logger) to stabilize and materialize first?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestIssues requesting new Node.js features.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions