monaco-yaml

YAML plugin for the Monaco Editor

Usage no npm install needed!

<script type="module">
  import monacoYaml from 'https://cdn.skypack.dev/monaco-yaml';
</script>

README

Monaco YAML

ci workflow npm version prettier code style demo netlify status

YAML language plugin for the Monaco Editor. It provides the following features when editing YAML files:

  • Code completion, based on JSON schemas or by looking at similar objects in the same file
  • Hovers, based on JSON schemas
  • Validation: Syntax errors and schema validation
  • Formatting using Prettier
  • Document Symbols
  • Automatically load remote schema files (by enabling DiagnosticsOptions.enableSchemaRequest)
  • Links from JSON references.
  • Links and hover effects from YAML anchors.

Schemas can also be provided by configuration. See here for the API that the plugin offers to configure the YAML language support.

Installation

npm install monaco-yaml

Usage

Import monaco-yaml and configure it before an editor instance is created.

import { editor, Uri } from 'monaco-editor';
import { setDiagnosticsOptions } from 'monaco-yaml';

// The uri is used for the schema file match.
const modelUri = Uri.parse('a://b/foo.yaml');

setDiagnosticsOptions({
  enableSchemaRequest: true,
  hover: true,
  completion: true,
  validate: true,
  format: true,
  schemas: [
    {
      // Id of the first schema
      uri: 'http://myserver/foo-schema.json',
      // Associate with our model
      fileMatch: [String(modelUri)],
      schema: {
        type: 'object',
        properties: {
          p1: {
            enum: ['v1', 'v2'],
          },
          p2: {
            // Reference the second schema
            $ref: 'http://myserver/bar-schema.json',
          },
        },
      },
    },
    {
      // Id of the first schema
      uri: 'http://myserver/bar-schema.json',
      schema: {
        type: 'object',
        properties: {
          q1: {
            enum: ['x1', 'x2'],
          },
        },
      },
    },
  ],
});

editor.create(document.createElement('editor'), {
  // Monaco-yaml features should just work if the editor language is set to 'yaml'.
  language: 'yaml',
  model: editor.createModel('p1: \n', 'yaml', modelUri),
});

Also make sure to register the web worker. When using Webpack 5, this looks like the code below. Other bundlers may use a different syntax, but the idea is the same. Languages you don’t used can be omitted.

window.MonacoEnvironment = {
  getWorker(moduleId, label) {
    switch (label) {
      case 'editorWorkerService':
        return new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker', import.meta.url));
      case 'css':
      case 'less':
      case 'scss':
        return new Worker(new URL('monaco-editor/esm/vs/language/css/css.worker', import.meta.url));
      case 'handlebars':
      case 'html':
      case 'razor':
        return new Worker(
          new URL('monaco-editor/esm/vs/language/html/html.worker', import.meta.url),
        );
      case 'json':
        return new Worker(
          new URL('monaco-editor/esm/vs/language/json/json.worker', import.meta.url),
        );
      case 'javascript':
      case 'typescript':
        return new Worker(
          new URL('monaco-editor/esm/vs/language/typescript/ts.worker', import.meta.url),
        );
      case 'yaml':
        return new Worker(new URL('monaco-yaml/yaml.worker', import.meta.url));
      default:
        throw new Error(`Unknown label ${label}`);
    }
  },
};

Examples

A demo is available on monaco-yaml.js.org.

A running example: demo-image

Some usage examples can be found in the examples directory.

FAQ

Does this work with the Monaco UMD bundle?

No. Only ESM is supported.

Does this work with Monaco Editor from a CDN?

No, because these use a UMD bundle, which isn’t supported.

Does this work with @monaco-editor/loader or @monaco-editor/react?

No. These packages pull in the Monaco UMD bundle from a CDN. Because UMD isn’t supported, neither are these packages.

Is the web worker necessary?

Yes. The web worker provides the core functionality of monaco-yaml.

Does it work without a bundler?

No. monaco-yaml uses dependencies from node_modules, so they can be deduped and your bundle size is decreased. This comes at the cost of not being able to use it without a bundler.

How do I integrate monaco-yaml with a framework? (Angular, React, Vue, etc.)

monaco-yaml only uses the Monaco Editor. It’s not tied to a framework, all that’s needed is a DOM node to attach the Monaco Editor to. See the Monaco Editor examples for examples on how to integrate Monaco Editor in your project, then configure monaco-yaml as described above.

Does monaco-yaml work with create-react-app?

Yes, but you’ll have to eject. See #92 (comment) for details.

Why isn’t monaco-yaml working? Official Monaco language extensions do work.

This is most likely due to the fact that monaco-yaml is using a different instance of the monaco-editor package than you are. This is something you’ll want to avoid regardless of monaco-editor, because it means your bundle is significantly larger than it needs to be. This is likely caused by one of the following issues:

  • A code splitting misconfiguration

    To solve this, try inspecting your bundle using for example webpack-bundle-analyzer. If monaco-editor is in there twice, this is the issue. It’s up to you to solve this, as it’s project-specific.

  • You’re using a package which imports monaco-editor for you, but it’s using a different version.

    You can find out why the monaco-editor is installed using npm ls monaco-editor or yarn why monaco-editor. It should exist only once, but it’s ok if it’s deduped.

    You may be able to solve this by deleting your node_modules folder and package-lock.json or yarn.lock, then running npm install or yarn install respectively.

Contributing

Please see our contributing guidelines

Credits

Originally @kpdecker forked this repository from monaco-json by @microsoft and rewrote it to work with yaml-language-server instead. Later the repository maintenance was taken over by @pengx17. Eventually the repository was tranferred to the account of @remcohaszing, who is currently maintaining this repository with the help of @fleon and @yazaabed.

The heavy processing is done in yaml-language-server, best known for being the backbone for vscode-yaml. This repository provides a thin layer to add functionality provided by yaml-language-server into monaco-editor.

License

MIT