Deno - Read and Write YAML FIles Examples

This tutorial shows you how to parse a YAML file in Deno and also how to write data to a file in YAML format.

YAML (YAML Ain't Markup Language) is a human-readable data-serialization language. YAML uses indentation to indicate nesting, [...] for lists and {...} for maps. It also has libraries available for many programming languages.

Deno itself has a module named yaml as part of Deno Standard Modules. It has the functionalities for formatting an object to YAML format and parsing a string in YAML format.

For this tutorial, let's assume we have these two files, one with a single document and the other with multi-documents.

data.yaml

  playerName: tuwaise
  monsters:
    - number: 1
      type: fire
    - number: 2
      type: water
    - number: 3
      type: grass

data2.yaml

  playerName: tuwaise
  monsters:
    - number: 1
      type: fire
    - number: 2
      type: water
    - number: 3
      type: grass
  ---
  playerName: chibi
  monsters:
    - number: 1
      type: ice
    - number: 2
      type: psychic

Using Deno std yaml Module

First, import and re-export the functions of yaml module in deps.ts file. There are three functions we are going to use.

  • parse: used to parse a yaml string to an object.
  • parseAll: used to parse a yaml string containing multi-documents to a list of objects.
  • stringify: used to format an object to YAML format.

deps.ts

  import {
    parse as yamlParse,
    parseAll as yamlParseAll,
    stringify as yamlStringify,
  } from 'https://deno.land/std@0.82.0/encoding/yaml.ts';

Parse YAML File

Below is the function that allows you to parse a string in YAML format to a JSON object.

  function parse(content: string, options?: ParseOptions): unknown

ParseOptions has the following fields:

  • legacy?: boolean: qqq.
  • listener?: ((...args: Any[]) => void) | null: qqq.
  • filename?: string: string to be used as a file path in error/warning message.
  • schema?: SchemaDefinition: qqq.
  • json?: boolean: Compatibility with JSON.parse behaviour.
  • onWarning?(this: null, e?: YAMLError): void: function to call on warning messages.

The function requires you to pass the content as a string. If you need to read the contents from a file, you can use Deno.readTextFile. Since the code requires access to read files, you need to add --allow-read flag while running deno run command.

Example:

  import { yamlParse } from './deps.ts';

  const data = yamlParse(await Deno.readTextFile('data.yaml'));
  console.log(data);

Output:

  {
    playerName: "tuwaise",
    monsters: [
      { number: 1, type: "fire" },
      { number: 2, type: "water" },
      { number: 3, type: "grass" }
    ]
  }

Make sure the file to be parsed contains a valid YAML format. Otherwise YAMLError will be thrown.

The parse function only works if the file contains a single document. If the file contains multi-documents, you need to use the parseAll function:

  function parseAll(
    content: string,
    iterator?: CbFunction,
    options?: ParseOptions,
  ): unknown

Example:

  import { yamlParseAll } from './deps.ts';

  const data = yamlParseAll(await Deno.readTextFile('data2.yaml'));
  console.log(data);

Output:

  [
    {
      playerName: "tuwaise",
      monsters: [
        { number: 1, type: "fire" },
        { number: 2, type: "water" },
        { number: 3, type: "grass" }
      ]
    },
    {
      playerName: "chibi",
      monsters: [ { number: 1, type: "ice" }, { number: 2, type: "psychic" } ]
    }
  ]

Write YAML File

The module also has a function named stringify that can be used to format an object to YAML format.

  function stringify(
    obj: Record<string, unknown>,
    options?: DumpOptions,
  ): string

You need to pass the object as the first argument. Optionally, you can also pass a second argument which is an object whose type is DumpOptions to customize the output format. DumpOptions has the following fields:

  • indent?: number: Indentation with in spaces.
  • noArrayIndent?: boolean: If true, it will not add an indentation level to array elements.
  • skipInvalid?: boolean: If true, it will not throw on invalid types and skip pairs and single values with such types.
  • flowLevel?: number: Specifies level of nesting, when to switch from block to flow style for collections. -1 means block style everywhere.
  • styles?: ArrayObject<StyleVariant> | null: Each tag may have its own set of styles. - "tag" => "style" map.
  • schema?: SchemaDefinition: The schema to use.
  • sortKeys?: boolean | ((a: string, b: string) => number): If true, sort keys when dumping YAML in ascending, ASCII character order. If a function, use the function to sort the keys. Defaults to false.
  • lineWidth?: number: Set the maximum line width. Defaults to 80.
  • noRefs?: boolean: If true, don't convert duplicate objects into references. Defaults to false.
  • noCompatMode?: boolean: If true, don't try to be compatible with older yaml versions.
  • condenseFlow?: boolean: If true flow sequences will be condensed, omitting the space between `key: value` or `a, b`.

Below is a basic usage example that doesn't pass the options argument. --allow-write flag needs to be added if you want to write the output to a file.

  const yaml = yamlStringify({
    playerName: 'tuwaise',
    monsters: [
      { number: 1, type: 'fire' },
      { number: 2, type: 'water' },
      { number: 3, type: 'grass' },
    ]
  });
  console.log(await Deno.writeTextFile('output.yaml', yaml));

Output:

  playerName: tuwaise
  monsters:
    - number: 1
      type: fire
    - number: 2
      type: water
    - number: 3
      type: grass

Here's another example with custom indent size and sorted keys.

  const yaml = yamlStringify(
    {
      playerName: 'tuwaise',
      monsters: [
          { number: 1, type: 'fire' },
          { number: 2, type: 'water' },
          { number: 3, type: 'grass' },
      ]
    },
    {
      indent: 3,
      sortKeys: true,
    }
  );
  console.log(await Deno.writeTextFile('output.yaml', yaml));

Output:

  monsters:
     -
        number: 1
        type: fire
     -
        number: 2
        type: water
     -
        number: 3
        type: grass
  playerName: tuwaise

Summary

That's how to parse data in YAML format and how to format data to YAML format. You can utilize yaml module which is part of Deno Standard Modules.