Osy#betaRun it on Osyrin: osyrin.com

Packages · User interface

Osysharp.MarkdownEditor

Add it and your application has a real editor over any Markdown property: rich and source modes, a document outline, tables, maths and diagrams, and a save that writes only the sections that changed. The data stays plain markdown underneath.

version1.2.0pin@1categoryUser interfacesourceAvailable · MIT

Use it

One line in the manifest, one call on a page

The manifest names the package; the editor kit depends on the platform's Markdown capability, which stores a document as its sections, so the app declares that too. Then a page hands the editor the address of a document: which entity, which row, which member. The editor reads and writes the sections behind that address under the entity's own rules.

demo/markdown-demo/app.osyverbatim — this file compiles
app MarkdownDemo {
  use Osysharp.Ui;
  use Osysharp.MarkdownEditor@1;

  // BASELINE-OUT `BL-3.2` (2026-09-22): markdown STORAGE is its own capability now. The editor kit
  // (`Osysharp.MarkdownEditor`) depends on it, and so does any entity holding a `Markdown` property.
  use Osysharp.Markdown;

  model "model/**/*.osy";
  tests "tests/**/*.test.osy";
}
demo/markdown-demo/model/pages/editor.osyverbatim — this file compiles
    MarkdownEditor(
      ownerType: "User",
      ownerId: me.Id,
      property: "Notes",
      face: editorial,
      outline: true,

Both listings are the app that draws the screenshot below, read at build time. ownerType, ownerId and property are the address; face and outline are choices. A reader the entity's rule does not let update the row gets a read-only document.

What it gives you

An editor, and a document that stays data

Two modes over one document
editing
A rendered mode for writing and a source mode for the markdown itself, over the same sections. Switching does not re-marshal the document.
Sections, and saves that cost what they changed
storage
The document is stored as one row per section, with an identity that survives edits. A save writes only the sections that changed, so ticking a checkbox is one row.
Structure
editing
A heading outline beside the document, a block handle and menu on every block, and commands that turn a block into a heading or delete it.
Tables, maths and diagrams
content
Tables in the editor; maths set with Temml; diagrams drawn with Mermaid. Maths and diagrams are separate chunks fetched the first time a document uses them, so a page of prose never pays for them.
Find and replace
editing
The matcher is the kit's and the bar is yours: the editor raises find events and takes FindNext, FindPrev, ReplaceOne, ReplaceAll and ClearFind, and the page draws whatever bar it wants in the editor's toolbar slot.
Your toolbar, your menu
extension
The Toolbar slot takes your own buttons wired to the editor's commands, and extraItems adds your own actions to the block menu, without forking.
Faces and density
appearance
A reading face (editorial, sans or serif), a density (comfortable or compact), read-only when you say so, and the theme tokens it reads are your app's.
Events
integration
saved(updated, created, deleted), dirty(isDirty), findRequested(selection) and matchesChanged(current, total), so the page can react to what the person did.

See it

Over a real document

The markdown editor over a signed-in user's notes on special relativity: rendered maths, and the outline rail listing every section
The demo app above: notes on special relativity with the maths rendered, the outline rail beside the document, and the app's own find bar in the toolbar slot.
The editor over a release-notes document, with its outline beside it
From the package's own README: the editor over a release-notes document, with its outline.

How it fits Osy#

A control declared in Osy#, over a shim it builds and pins

The package's public surface is one declaration, control MarkdownEditor in markdown.osy: the props, the slot, the events and the commands a page can use, exactly as it would use any other control. Behind it is a TypeScript shim over Milkdown and CodeMirror, bundled and checked in, with a typed ABI generated from the declaration so the shim is held to the same public control surface your own controls get. The kit pins its bundle and its maths and diagram chunks by content address in its own osyrin.lock.

It is a package rather than a platform feature so that an app which does not edit documents carries no editor. And because the owner of a package is its GitHub owner, forking it is renaming it: package Acme.Markdown lives at github.com/acme/markdown, built with osy control build and published with osy publish.

Reference

Every prop, event and command

This page says what the package is and what you can do with it. The reference says exactly how each option behaves, what the editor costs, the theme tokens it reads, and the traps that cost real time: the markdown editor kit, and osy docs ui-markdown-editor-kit at the terminal.

Source and release

Public, MIT, released on GitHub

Sourcegithub.com/osysharp/markdowneditor
LicenceMIT. The Osy# source is yours to read, copy, fork and ship; the vendored bundle wraps Milkdown, CodeMirror 6, Mermaid and Temml, all MIT, and THIRD-PARTY-NOTICES.md names them.
ReleaseLatest release. Every release carries package.zip, the archive osy lock downloads and verifies by content address; use Osysharp.MarkdownEditor@1; resolves the newest 1.x.
Manifestversion 1.2.0, builds on Osysharp.Markdown