front-matter vs yaml-front-matter vs gray-matter
Parsing Front Matter in Static Site Generators and Build Tools
front-matteryaml-front-mattergray-matterSimilar Packages:

Parsing Front Matter in Static Site Generators and Build Tools

front-matter, gray-matter, and yaml-front-matter are utilities designed to extract metadata (front matter) from the top of files, typically Markdown or text files. This metadata is often used in static site generators (like Jekyll, Hexo, or Next.js) to define page titles, dates, layouts, and other configuration. While they share the same core purpose, they differ significantly in supported formats (YAML, JSON, TOML), parsing engines, extensibility, and current maintenance status. gray-matter is generally the most robust and actively maintained, while yaml-front-matter is often considered legacy.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
front-matter6,194,863695-326 years agoMIT
yaml-front-matter85,499195-215 years agoMIT
gray-matter04,396-695 years agoMIT

Parsing Front Matter: front-matter vs gray-matter vs yaml-front-matter

When building static sites, documentation tools, or content management systems, you often need to store metadata at the top of a file. This is called "front matter." It usually sits between delimiters (like ---) and contains YAML, JSON, or TOML. Three common packages handle this in the JavaScript ecosystem: front-matter, gray-matter, and yaml-front-matter. While they solve the same problem, their capabilities and maintenance status vary widely.

🛠️ Core Parsing Capabilities: YAML vs JSON vs TOML

The most critical difference is what data formats each package supports out of the box.

front-matter focuses primarily on YAML.

  • It uses the js-yaml library under the hood.
  • It is strict about YAML syntax by default.
  • Does not support JSON or TOML without custom configuration.
// front-matter: YAML only by default
import fm from 'front-matter';

const file = `---
title: Hello
---
Content here`;

const result = fm(file);
console.log(result.attributes.title); // "Hello"

gray-matter supports multiple languages natively.

  • You can parse YAML, JSON, and even TOML.
  • It auto-detects the language based on delimiters or options.
  • Great for projects mixing different config formats.
// gray-matter: Multi-language support
import matter from 'gray-matter';

// YAML
const yamlFile = matter(`---
title: Hello
---
Content`);

// JSON
const jsonFile = matter(`+++json
{
  "title": "Hello"
}
+++
Content`);

console.log(yamlFile.data.title); // "Hello"
console.log(jsonFile.data.title); // "Hello"

yaml-front-matter is strictly for YAML.

  • As the name implies, it does not handle JSON or TOML.
  • It is older and less flexible than gray-matter.
  • Best suited for legacy projects that specifically require this narrow scope.
// yaml-front-matter: Strictly YAML
import yfm from 'yaml-front-matter';

const file = `---
title: Hello
---
Content here`;

const result = yfm.loadFront(file);
console.log(result.title); // "Hello"
// Note: API returns attributes directly on the object, not nested

🔧 API Design: Object Structure and Stringifying

How you access the data and write it back differs between these libraries. This affects how much boilerplate code you write.

front-matter returns a structured object.

  • attributes holds the metadata.
  • body holds the content.
  • Does not have a built-in way to write front matter back to a string easily.
// front-matter: Read-only structure
import fm from 'front-matter';

const result = fm(file);
const meta = result.attributes;
const content = result.body;

// No built-in stringify method to reconstruct the file

gray-matter offers a symmetric API (read and write).

  • data holds the metadata.
  • content holds the body.
  • Includes .stringify() to write changes back to disk cleanly.
// gray-matter: Read and Write
import matter from 'gray-matter';

const file = matter(fileString);
file.data.title = "Updated Title";

// Reconstruct the file with new front matter
const newFile = matter.stringify(file.content, file.data);

yaml-front-matter merges metadata into the result.

  • The returned object contains both content and attributes mixed.
  • __content property usually holds the body.
  • Less clear separation of concerns compared to gray-matter.
// yaml-front-matter: Merged result
import yfm from 'yaml-front-matter';

const result = yfm.loadFront(file);
const title = result.title; // Direct access
const content = result.__content; // Body is a property

// No built-in stringify method

⚙️ Customization: Delimiters and Engines

Real-world projects often need custom delimiters (like +++ for Hugo) or custom parsing logic.

front-matter allows some delimiter config.

  • You can change the opening and closing markers.
  • Limited ability to swap the parsing engine.
// front-matter: Custom delimiters
import fm from 'front-matter';

// Configuring delimiters is less straightforward 
// often requires passing options to the function if supported
// or relying on default '---'
const result = fm(file, { delimiters: '+++' }); 

gray-matter is highly extensible.

  • Easily change delimiters (e.g., +++ for TOML).
  • You can plug in custom engines for exotic formats.
  • Supports strict mode to fail on invalid YAML.
// gray-matter: Custom delimiters and engines
import matter from 'gray-matter';

// Using +++ for TOML or custom YAML
const file = matter(fileString, {
  delimiters: '+++',
  engines: {
    yaml: require('js-yaml').safeLoad
  }
});

yaml-front-matter has minimal configuration.

  • Mostly sticks to defaults.
  • Harder to adapt for non-standard project structures.
  • Lacks the plugin architecture of gray-matter.
// yaml-front-matter: Limited config
import yfm from 'yaml-front-matter';

// Mostly relies on default '---' delimiters
// Harder to customize parsing behavior
const result = yfm.loadFront(file);

🚨 Maintenance and Ecosystem Health

This is a critical architectural decision factor. Using unmaintained packages introduces security and compatibility risks.

front-matter is stable but slower moving.

  • It is widely used and considered reliable for YAML.
  • Updates are infrequent but it remains functional.
  • Good for simple, long-term stable projects.

gray-matter is the active standard.

  • Maintained by prominent ecosystem contributors.
  • Regularly updated to fix bugs and support new Node versions.
  • Used by major tools like VuePress and many static site generators.

yaml-front-matter is effectively legacy.

  • Development has slowed significantly.
  • Many modern tools have migrated away from it to gray-matter.
  • Not recommended for new architecture unless required for legacy compatibility.

📊 Summary Table

Featurefront-mattergray-matteryaml-front-matter
Primary FormatYAMLYAML, JSON, TOMLYAML
Stringify Support❌ No✅ Yes❌ No
Custom Delimiters⚠️ Limited✅ Yes❌ No
API Style{ attributes, body }{ data, content }Merged Object
MaintenanceStableActiveLegacy
Best ForSimple YAML parsingModern SSG / Build ToolsLegacy Maintenance

💡 The Big Picture

gray-matter is the clear winner for modern development. It handles the complexity of different formats, allows you to write data back to files easily, and is actively maintained. It saves you from writing boilerplate code to handle edge cases.

front-matter is a decent runner-up if you only care about YAML and want a very lightweight dependency without the extra features of gray-matter. It is safe to use but offers less flexibility.

yaml-front-matter should generally be avoided in new projects. It lacks the features and maintenance cadence of the other two. Only use it if you are stuck maintaining an older system that depends on its specific API behavior.

Final Thought: In 2024 and beyond, gray-matter is the architectural standard for front matter parsing. It balances power, flexibility, and stability better than the alternatives.

How to Choose: front-matter vs yaml-front-matter vs gray-matter

  • front-matter:

    Choose front-matter if you need a lightweight, stable parser specifically for YAML front matter and want to stick with the js-yaml engine directly. It is a solid choice for simple use cases where you do not need JSON or TOML support, and you prefer a minimal API surface without extra abstraction layers.

  • yaml-front-matter:

    Avoid yaml-front-matter for new projects as it is largely considered legacy and less actively maintained compared to gray-matter. Only choose this if you are maintaining an older codebase that already depends on it and refactoring is not feasible, or if you have a very specific requirement for its narrow YAML-only implementation that matches an old workflow.

  • gray-matter:

    Choose gray-matter for most modern projects, especially if you need support for multiple languages (YAML, JSON, TOML) or custom delimiters. It is actively maintained, highly extensible with custom engines, and offers the best developer experience with features like stringifying content back with front matter intact. It is the industry standard for this task.

README for front-matter

front-matter

build coverage npm github

Sauce Test Status

Extract meta data (front-matter) from documents.

This modules does not do any IO (file loading or reading), only extracting and parsing front matter from strings.

This concept that was originally introduced to me through the jekyll blogging system and is pretty useful where you want to be able to easily add meta-data to content without the need for a database. YAML is extracted from the the top of a file between matching separators of "---" or "= yaml =". It will also extract YAML between a separator and "...".

Install

With npm do:

npm install front-matter

Example

So you have a file example.md:

---
title: Just hack'n
description: Nothing to see here
---

This is some text about some stuff that happened sometime ago

NOTE: As of front-matter@2.0.0 valid front matter is considered to have the starting separator on the first line.

Then you can do this:

var fs = require('fs')
  , fm = require('front-matter')

fs.readFile('./example.md', 'utf8', function(err, data){
  if (err) throw err

  var content = fm(data)

  console.log(content)
})

And end up with an object like this:

{
    attributes: {
        title: 'Just hack\'n',
        description: 'Nothing to see here'
    },
    body: 'This is some text about some stuff that happened sometime ago',
    bodyBegin: 6,
    frontmatter: 'title: Just hack\'n\ndescription: Nothing to see here'
}

Methods

var fm = require('front-matter')

fm(string, { allowUnsafe: false })

Return a content object with two properties:

  • content.attributes contains the extracted yaml attributes in json form
  • content.body contains the string contents below the yaml separators
  • content.bodyBegin contains the line number the body contents begins at
  • content.frontmatter contains the original yaml string contents

NOTE: By default fm() uses ys-yaml's safeLoad unless you set allowUnsafe in the options object to true.

fm.test(string)

Check if a string contains a front matter header of "---" or "= yaml =". Primarily used internally but is useful outside of the module.

Returns true or false

    fm.test(string) #=> true || false

Contributing

front-matter is an OPEN Source Project so please help out by reporting bugs or forking and opening pull requests when possible.

standard

All code is linted/formatted using standard style, any non-conforming code can be automatically formatted using the the fmt make task: make fmt.

Maintainers

Contributors

This module is awesome because of all the folks who submitted pull requests:

CHANGELOG

3.0.0

  • CI only tests Node versions >= v6 (drops v4, and v5)

LICENSE (MIT)

Copyright (c) Jason Campbell ("Author")

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.