YAML plugin for the Monaco Editor
npm install monaco-yaml




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.
- Code folding.
Schemas can also be provided by configuration. See
here for the API that the plugin
offers to configure the YAML language support.
- Installation
- Usage
- Examples
- API
- configureMonacoYaml(monaco, options?)
- FAQ
- Does this work with the Monaco UMD bundle?
- Does this work with Monaco Editor from a CDN?
- Does this work with @monaco-editor/loader or @monaco-editor/react?
- Is the web worker necessary?
- Does it work without a bundler?
- How do I integrate monaco-yaml with a framework? (Angular, React, Vue, etc.)
- Does monaco-yaml work with create-react-app?
- Why doesn’t it work with Vite?
- Why isn’t monaco-yaml working? Official Monaco language extensions do work.
- Using Monaco webpack loader plugin
- Why is syntax highlighting not working?
- Why does it try to download my schema even when I provided one as an object?
- Contributing
- Credits
- License
``sh`
npm install monaco-yaml
Before implementing monaco-yaml, or even Monaco editor, it’s recommended to learn the
basic concepts of Monaco editor.
To configure monaco-yaml, call configureMonacoYaml.
`typescript
import * as monaco from 'monaco-editor'
import { configureMonacoYaml } from 'monaco-yaml'
configureMonacoYaml(monaco, {
enableSchemaRequest: true,
schemas: [
{
// If YAML file is opened matching this glob
fileMatch: ['*/.prettierrc.'],
// Then this schema will be downloaded from the internet and used.
uri: 'https://json.schemastore.org/prettierrc.json'
},
{
// If YAML file is opened matching this glob
fileMatch: ['**/person.yaml'],
// The following schema will be applied
schema: {
type: 'object',
properties: {
name: {
type: 'string',
description: 'The person’s display name'
},
age: {
type: 'integer',
description: 'How old is the person in years?'
},
occupation: {
enum: ['Delivery person', 'Software engineer', 'Astronaut']
}
}
},
// And the URI will be linked to as the source.
uri: 'https://github.com/remcohaszing/monaco-yaml#usage'
}
]
})
const prettierc = monaco.editor.createModel(
'singleQuote: true\nproseWrap: always\nsemi: yes\n',
undefined,
monaco.Uri.parse('file:///.prettierrc.yaml')
)
monaco.editor.createModel(
'name: John Doe\nage: 42\noccupation: Pirate\n',
undefined,
monaco.Uri.parse('file:///person.yaml')
)
monaco.editor.create(document.getElementById('editor'), {
automaticLayout: true,
model: prettierc
})
`
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.
`jsUnknown label ${label}
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()`
}
}
}
A demo is available on monaco-yaml.js.org.
Some usage examples can be found in the
examples directory.
monaco-yaml has the following exports:
Configure monaco-yaml.
> Note: There may only be one configured instance of monaco-yaml at a time.
#### Arguments
- monaco (object): The Monaco editor module. Typically you get this by importingmonaco-editor
. Third party integrations often expose it as the global monaco variable instead.options
- (object): Options to configure monaco-yaml.
#### Options
- completion (boolean): If set, enable schema based autocompletion. (Default: true)customTags
- (string[]): A list of custom tags. (Default: [])enableSchemaRequest
- (boolean): If set, the schema service will load schema content on-demand.false
(Default: )format
- (boolean): Prettier from the bundle. (Default: true)hover
- (boolean): If set, enable hover typs based the JSON schema. (Default: true)isKubernetes
- (boolean): If true, a different diffing algorithm is used to generate errorfalse
messages. (Default: )schemas
- (object[]): A list of known schemas and/or associations of schemas to file names.[]
(Default: )validate
- (boolean): based validation. (Default: true)yamlVersion
- ('1.1' | '1.2'): The YAML version to use for parsing. (Default: 1,2)
#### Returns
An object that can be used to dispose or update monaco-yaml.
Yes, starting from version 5.0.0
Yes, starting from version 5.0.0
Yes, starting from version 5.0.0
Yes. The web worker provides the core functionality of monaco-yaml.
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.
monaco-yaml only uses the Monaco Editor. It’s not tied to a framework, all that’s needed is a DOMmonaco-yaml
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 as described above.
Yes, but you’ll have to eject. See
#92 (comment) for
details.
Some users have experienced the following error when using Vite:
``
Uncaught (in promise) Error: Unexpected usage
at EditorSimpleWorker.loadForeignModule (editorSimpleWorker.js)
at webWorker.js
As a workaround, create a file named yaml.worker.js in your own project with the following
contents:
`js`
import 'monaco-yaml/yaml.worker.js'
Then in your Monaco environment getWorker function, reference this file instead of referencingmonaco-yaml/yaml.worker.js directly:
`js
import YamlWorker from './yaml.worker.js?worker'
window.MonacoEnvironment = {
getWorker(moduleId, label) {
switch (label) {
// Handle other cases
case 'yaml':
return new YamlWorker()
default:
throw new Error(Unknown label ${label})`
}
}
}
This is most likely due to the fact that monaco-yaml is using a different instance of themonaco-editor package than you are. This is something you’ll want to avoid regardless ofmonaco-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 oryarn 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 oryarn.lock
, then running npm install or yarn install respectively.
If you’re using
monaco webpack plugin, then
instead of the above code, you can extend the plugin’s configuration. Extend your
webpack.config.js file with the following:
`js
import { MonacoWebpackPlugin } from 'monaco-editor-webpack-plugin'
export default {
// ...the rest of your webpack configuration...
plugins: [
new MonacoWebpackPlugin({
languages: ['yaml'],
customLanguages: [
{
label: 'yaml',
entry: 'monaco-yaml',
worker: {
id: 'monaco-yaml/yamlWorker',
entry: 'monaco-yaml/yaml.worker'
}
}
]
})
]
}
`
You can also refer to the
example
of a complete project.
Syntax highlighting is provided by Monaco editor itself, not by monaco-yaml. If you use a buildyaml
tool to filter languages or features, make sure to include the language. If you import Monacomonaco-editor/esm/vs/editor/editor.api.js
editor from and cherry-pick features manually, make suremonaco-editor/esm/vs/basic-languages/yaml/yaml.contribution.js
to also import . If you usemonaco-editor-core, make sure to import monaco-languages/release/esm/yaml/yaml.contribution.js.
You may have provided a schema configured like this:
`Javascript`
{
uri: "http://example.com",
fileMatch: ["file_name.yml"],
schema: {
$schema: "http://json-schema.org/draft-07/schema#",
$id: "http://example.com",
title: "placeholder title",
description: "placeholder description",
type: "object",
properties: {
name: {
description: "name property description",
type: "string",
},
},
required: ["name"],
},
}
And would be surprised to see the error:
> Unable to load schema from '
It happens because plugin uses schema URI not only as the URL to download the schema from, but also
to determine the schema name. To fix this, change the uri parameter tohttp://example.com/schema-name.json.
Please see our contributing guidelines
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 intomonaco-editor`.