File: custom_types.md | Updated: 11/15/2025
This example demonstrates how to define custom YAML types for JavaScript classes and use them to load and dump YAML documents with custom tags.
Custom types allow you to:
We define two classes: Point and Space.
function Point(x, y, z) {
this.klass = 'Point';
this.x = x;
this.y = y;
this.z = z;
}
function Space(height, width, points) {
if (points) {
if (!points.every(function (point) { return point instanceof Point; })) {
throw new Error('A non-Point inside a points array!');
}
}
this.klass = 'Space';
this.height = height;
this.width = width;
this.points = points;
}
var PointYamlType = new yaml.Type('!point', {
// Loader must parse sequence nodes only for this type (i.e. arrays in JS terminology).
// Other available kinds are 'scalar' (string) and 'mapping' (object).
kind: 'sequence',
// Loader must check if the input object is suitable for this type.
resolve: function (data) {
// `data` may be either:
// - Null in case of an "empty node"
// - Array since we specified `kind` to 'sequence'
return data !== null && data.length === 3;
},
// If a node is resolved, use it to create a Point instance.
construct: function (data) {
return new Point(data[0], data[1], data[2]);
},
// Dumper must process instances of Point by rules of this YAML type.
instanceOf: Point,
// Dumper must represent Point objects as three-element sequence in YAML.
represent: function (point) {
return [ point.x, point.y, point.z ];
}
});
var SpaceYamlType = new yaml.Type('!space', {
kind: 'mapping',
construct: function (data) {
data = data || {}; // in case of empty node
return new Space(data.height || 0, data.width || 0, data.points || []);
},
instanceOf: Space
// `represent` is omitted here. So, Space objects will be dumped as is.
// That is regular mapping with three key-value pairs but with !space tag.
});
var SPACE_SCHEMA = yaml.DEFAULT_SCHEMA.extend([ SpaceYamlType, PointYamlType ]);
fs.readFile(path.join(__dirname, 'custom_types.yml'), 'utf8', function (error, data) {
var loaded;
if (!error) {
loaded = yaml.load(data, { schema: SPACE_SCHEMA });
console.log(util.inspect(loaded, false, 20, true));
} else {
console.error(error.stack || error.message || String(error));
}
});
subject: Custom types in JS-YAML
spaces:
- !space
height: 1000
width: 1000
points:
- !point [ 10, 43, 23 ]
- !point [ 165, 0, 50 ]
- !point [ 100, 100, 100 ]
- !space
height: 64
width: 128
points:
- !point [ 12, 43, 0 ]
- !point [ 1, 4, 90 ]
- !space # An empty space
'use strict';
var fs = require('fs');
var path = require('path');
var util = require('util');
var yaml = require('../');
// Let's define a couple of classes.
function Point(x, y, z) {
this.klass = 'Point';
this.x = x;
this.y = y;
this.z = z;
}
function Space(height, width, points) {
if (points) {
if (!points.every(function (point) { return point instanceof Point; })) {
throw new Error('A non-Point inside a points array!');
}
}
this.klass = 'Space';
this.height = height;
this.width = width;
this.points = points;
}
// Then define YAML types to load and dump our Point/Space objects.
var PointYamlType = new yaml.Type('!point', {
kind: 'sequence',
resolve: function (data) {
return data !== null && data.length === 3;
},
construct: function (data) {
return new Point(data[0], data[1], data[2]);
},
instanceOf: Point,
represent: function (point) {
return [ point.x, point.y, point.z ];
}
});
var SpaceYamlType = new yaml.Type('!space', {
kind: 'mapping',
construct: function (data) {
data = data || {};
return new Space(data.height || 0, data.width || 0, data.points || []);
},
instanceOf: Space
});
// After our types are defined, it's time to join them into a schema.
var SPACE_SCHEMA = yaml.DEFAULT_SCHEMA.extend([ SpaceYamlType, PointYamlType ]);
// And read a document using that schema.
fs.readFile(path.join(__dirname, 'custom_types.yml'), 'utf8', function (error, data) {
var loaded;
if (!error) {
loaded = yaml.load(data, { schema: SPACE_SCHEMA });
console.log(util.inspect(loaded, false, 20, true));
} else {
console.error(error.stack || error.message || String(error));
}
});
// There are some exports to play with this example interactively.
module.exports.Point = Point;
module.exports.Space = Space;
module.exports.PointYamlType = PointYamlType;
module.exports.SpaceYamlType = SpaceYamlType;
module.exports.SPACE_SCHEMA = SPACE_SCHEMA;