Web quick start
Documentation index ยท JavaScript API
Run the demo
In the full project, open CODE-Editor-Demo.html for the self-contained demo. For development, use index.html with its adjacent sources. You can also run this from the full project root:
node tools/serve.cjs
Visit http://127.0.0.1:8091. The Node helper serves static files; it does not implement the ASP.NET image-upload endpoint. A file:// demo likewise provides no application storage. Rebuild the one-file demo after source changes with node tools/bundle.cjs.
Complete embedding example
Save the following HTML beside the full project's JavaScript/CSS sources. The editor pane and preview share a container; the component creates the resize divider. This example uses no demonstration toolbar or draft-storage code.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>CODE Editor example</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="features.css">
<style>
body { margin: 16px; font-family: system-ui, sans-serif; }
#workspace { height: 70vh; min-height: 280px; }
#editor-pane { position: relative; min-width: 0; min-height: 0; }
#editor { height: 100%; overflow: auto; padding: 20px 20px 20px 52px; }
#preview { height: 100%; width: 100%; border: 0; }
</style>
</head>
<body>
<button id="bold" type="button">Bold</button>
<div id="workspace">
<div id="editor-pane">
<div id="gutter" aria-hidden="true"></div>
<div id="editor" class="editing-surface"></div>
</div>
<iframe id="preview" title="Document preview" hidden sandbox></iframe>
</div>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/codecs.js"></script>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/core.js"></script>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/commands.js"></script>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/documents.js"></script>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/structures.js"></script>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/policy.js"></script>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/markdown-commands.js"></script>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/preview.js"></script>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/languages.js"></script>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/paste.js"></script>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/surface.js"></script>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/editor.js"></script>
<script src="/___FileProxy___?mode=vstsgit&path=DevProcess/TextEditor/advanced.js"></script>
<script>
const editor = CODEEditor.create(document.querySelector('#editor'), {
value: '# My document\n\nSelect some text and press Ctrl+B.',
format: 'markdown', mode: 'source', language: 'markdown',
preset: 'full', allowEmbeddedHtml: false,
wrap: true, decorated: true, lineNumbers: true,
label: 'Document',
gutter: document.querySelector('#gutter'),
editorPane: document.querySelector('#editor-pane'),
preview: document.querySelector('#preview'),
previewSync: true, previewSplit: 0.5
});
editor.setPreviewVisible(true);
document.querySelector('#bold').addEventListener('click', () => {
editor.execute('format', { mark: 'bold' });
editor.focus();
});
const unsubscribe = editor.on(event => {
if (event.type === 'status' || event.type === 'previewError') {
console.info(event.message);
}
});
// At teardown, after composition has committed:
// unsubscribe(); editor.destroy();
</script>
</body>
</html>
Keep the script order. advanced.js replaces the exported constructor/factory with the current implementation; omitting it loses structured editing, policy, image imports, and the current preview pipeline. app.js and feature-ui.js belong to the demo. image-host.js is an optional sample transport helper.
The surface needs a measurable constrained height and scrolling. Supply editorPane explicitly when wrappers make the pane ambiguous. The supplied stylesheet includes demonstration-wide selectors; web applications may want to scope or extract the editor-specific rules after testing. The WinForms control uses an additional control.css shell.
Load and switch views
editor.setValue('# Loaded note\n\nHello.', {
format: 'markdown', mode: 'rich', language: 'markdown'
});
editor.setMode('source');
editor.setMode('rich');
setValue loads a document, resets history/bookmarks, and establishes a saved baseline. Use commands for undoable edits. convertFormat explicitly converts Markdown/HTML; changing the source language does not.
Save through the host
Here persistDocument is a host function you implement:
async function saveDocument() {
const snapshot = editor.getSnapshot();
await persistDocument(snapshot.value, snapshot.format);
const stillCurrent = editor.markSaved(snapshot.revision, snapshot.sessionId);
if (!stillCurrent) {
// This snapshot was saved, but the user has a newer unsaved revision.
}
}
Handle failures from both snapshot creation and storage. Active composition, policy violations, and pending/failed image imports can block snapshots. Never acknowledge a failed write.
Configuration and lifecycle
editor.configure({ wrap: false, tabWidth: 4, indentWithTabs: false });
editor.setReadOnly(true);
editor.setTheme('dark');
editor.configure({ previewCss: 'body { font-family: Georgia, serif; }' });
configure handles the documented presentation/policy/preview settings; it is not a general assignment of every constructor key. Supply image origins, image import callbacks, and image import settings at construction. A direct JavaScript host needing different construction-only settings should recreate the instance from a validated snapshot. The WinForms bridge separately synchronizes its image options.
Toolbar clicks can use the model's retained selection. For an asynchronous dialog, capture/restore/release a bookmark; stop if restore fails. The state guide explains why revision guards are also needed for delayed content replacement.
The JavaScript component supplies search methods and emits shortcut events for Ctrl/Cmd+F, H and G. Your host supplies that UI. On teardown, call destroy() to release subscriptions and imports. Committed-value operations and destruction refuse active composition, so arrange teardown after input composition completes.