TypeScript icon, indicating that this package has built-in type declarations

    3.7.4 • Public • Published


    NPM ISC License PRs Welcome Downloads
    VS Code unified
    TypeScript Prettier EditorConfig ESLint

    Validate Markdown frontmatter YAML against an associated JSON schema with this remark-lint rule plugin.


    • Types validation, pattern, enumerations,… and all you can get with JSON Schema
    • Code location problems indicator (for IDE to underline)
    • Auto-fixes with suggestions
    • Command Line Interface reporting
    • VS Code integration (see below)
    • Global patterns or in-file schemas associations
    • In JS framework MD / MDX pipelines


    Demo screenshot of frontmatter schema linter 1

    Demo screenshot of frontmatter schema linter 2

    Demo screenshot of frontmatter schema linter 3

    👉  Play with pre-configured ./demo

    Quick shallow clone with:

    pnpx degit JulianCataldo/remark-lint-frontmatter-schema/demo ./demo

    Jump to:



    pnpm install -D \
    remark remark-cli \
    remark-frontmatter \

    Remove -D flag for runtime unified MD / MDX pipeline (custom, Astro, Gatsby, etc.), for production.
    Keep it if you just want to lint with CLI or your IDE locally, without any production / CI needs.

    VS Code (optional)

    code --install-extension unifiedjs.vscode-remark


    CLI / IDE (VS Code) — Static linting

    👉  See ./demo folder to get a working, pre-configured, bare project workspace.
    You also get example Markdown files and associated schema to play with.
    Supports remark-cli and/or unifiedjs.vscode-remark extension.

    📌  Check out the demo/README.md for bootstrapping it.


    Create root config file for remark to source from:
    touch ./.remarkrc.mjs

    Paste this base config:

    import remarkFrontmatter from 'remark-frontmatter';
    import rlFmSchema from '@julian_cataldo/remark-lint-frontmatter-schema';
    const remarkConfig = {
      plugins: [remarkFrontmatter, rlFmSchema],
    export default remarkConfig;

    Schema example


    type: object
        type: string

    Schemas associations

    Inspired by VS Code JSON Schema and redhat.vscode-yaml conventions.

    Inside frontmatter

    See ./demo/content files for examples.

    Schema association can be done directly inside the frontmatter of the Markdown file, relative to project root, thanks to the '$schema' key:

    '$schema': /content/creative-work.schema.yaml
    title: Hello there
    category: Book
    # You're welcome!
    🌝  My **Markdown** content…  🌚
    🆕  Globally, with patterns

    Locally defined '$schema' takes precedence over global settings below.

    const remarkConfig = {
      plugins: [
            schemas: {
              /* One schema for many files */
              './content/creative-work.schema.yaml': [
                /* Support glob patterns */
                /* Or direct file association */
              './content/ghost.schema.yaml': [

    './foo', '/foo', 'foo', all will work.
    It's always relative to your ./.remarkrc.mjs file, in your workspace root.

    CLI usage

    Linting whole workspace files (as ./**/*.md) with remark-cli:

    pnpm remark .


      1:1  warning  /category: Must be equal to one of the allowed values  frontmatter-schema  remark-lint
      1:1  warning  /complex/some: Must be string                          frontmatter-schema  remark-lint
    ⚠ 6 warnings

    MD / MDX pipeline — Runtime validation

    Use it as usual like any remark plugin inside your framework or your custom unified pipeline.

    🆕  Custom pipeline

    When processing Markdown as single files inside your JS/TS app.

    Schema should be provided programmatically like this:

    // …
    import remarkFrontmatter from 'remark-frontmatter';
    import rlFmSchema from '@julian_cataldo/remark-lint-frontmatter-schema';
    import type { JSONSchema7 } from 'json-schema';
    import { reporter } from 'vfile-reporter';
    const mySchema: JSONSchema7 = {
      /* … */
    const output = await unified()
      // Your pipeline (basic example)
      // …
      .use(rlFmSchema, {
        /* Bring your own schema */
        embed: mySchema,
      // …
    /* `path` is for debugging purpose here, as MD literal comes from your app. */
    output.path = './the-current-processed-md-file.md';


      1:1  warning  Must have required property 'tag'  frontmatter-schema  remark-lint
    ⚠ 1 warning
    Implementation living example

    Checkout Astro Content repository.

    Astro Content relies on this library, among others, for providing linting reports.

    Important foot-notes for custom pipeline

    This is different from static linting, with VS Code extension or CLI.
    It will not source .remarkrc (but you can source it by your own means, if you want).
    In fact, it's not aware of your file structure, nor it will associate or import any schema / Markdown files.
    That way, it will integrate easier with your own business logic and existing pipelines.
    I found that static linting (during editing) / and runtime validation are two different uses cases enough to separate them in their setups, but I might converge them partially.


    WIP. NOT tested yet!

    See global patterns schemas associations for settings reference.


    In astro.config.mjs

    // …
    export default defineConfig({
      // …
      remarkPlugins: [
        // …
        ['@julian_cataldo/remark-lint-frontmatter-schema', { schemas }],
        // …
      // …

    In gatsby-config.js

      // …
      plugins: [
        // …
          resolve: 'gatsby-transformer-remark',
          options: {
            plugins: [
              // …
              ['@julian_cataldo/remark-lint-frontmatter-schema', { schemas }],
              // …
        // …


    export interface Settings {
       * Global workspace file associations mapping (for linter extension).
       * Example: `'schemas/thing.schema.yaml': ['content/things/*.md']`
      schemas?: Record<string, string[]>;
       * Direct schema embedding (for using inside an `unified` transform pipeline).
       * Format: JSON Schema - draft-2019-09
       * **Documentation**: https://ajv.js.org/json-schema.html#draft-07
      embed?: JSONSchema7;
       * **Documentation**: https://ajv.js.org/options.html
      ajvOptions?: AjvOptions;
    export interface FrontmatterSchemaMessage extends VFileMessage {
      schema: AjvErrorObject & { url: JSONSchemaReference };

    Example of a VFileMessage content you could collect from this lint rule:

      // …
        // JS native `Error`
        "name": "Markdown YAML frontmatter error (JSON Schema)",
        "message": "Keyword: type\nType: string\nSchema path: #/properties/title/type",
        // `VFileMessage` (Linter / VS Code…)
        "reason": "/clientType: Must be equal to one of the allowed values",
        "line": 16,
        "column": 13,
        "url": "https://github.com/JulianCataldo/remark-lint-frontmatter-schema",
        "source": "remark-lint",
        "ruleId": "frontmatter-schema",
        "position": {
          "start": {
            "line": 16,
            "column": 13
          "end": {
            "line": 16,
            "column": 24
        "fatal": false,
        "actual": "Individuaaaaaaaal",
        "expected": ["Corporate", "Non-profit", "Individual"],
        // Condensed string, human readable version of AJV error object
        "note": "Keyword: enum\nAllowed values: Corporate, Non-profit, Individual\nSchema path: #/properties/clientType/enum",
        // AJV's `ErrorObject`
        "schema": {
          "url": "https://ajv.js.org/json-schema.html",
          "instancePath": "/clientType",
          "schemaPath": "#/properties/clientType/enum",
          "keyword": "enum",
          "params": {
            "allowedValues": ["Corporate", "Non-profit", "Individual"]
          "message": "must be equal to one of the allowed values"


    • [ ] "@julian_cataldo/remark-lint-frontmatter-schema" is way too verbose for a package name.
      Must migrate it to "remark-lint-frontmatter-schema".


    100% ESM, including dependencies.


    Major dependencies:

    ajv, yaml, remark, remark-frontmatter, unified, remark-cli

    See CHANGELOG.md for release history.

    Related projects:

    • retext-case-police: Check popular names casing. Example: ⚠️ github GitHub.
    • remark-embed: A remark plugin for embedding remote / local Markdown or code snippets.
    • astro-content: A text based, structured content manager, for edition and consumption.

    🔗  JulianCataldo.com


    npm i @julian_cataldo/remark-lint-frontmatter-schema

    DownloadsWeekly Downloads






    Unpacked Size

    39.5 kB

    Total Files


    Last publish


    • julian.cataldo