Incremental Markdown parsing for live editors.
Cindermark gives Swift editors parser-backed structure, UTF-16 source ranges, and focused re-parsing after every change. Its Rust core ships with first-class bindings for iOS and macOS.
iOS 16+ · macOS 13+
Prebuilt XCFramework
Pure Rust crate
Type. Watch it parse.
Edit the note itself. Markdown marks appear when the caret needs them; tasks and table cells remain directly useful. The same parser model was built for Ember’s native editor, while this browser treatment stays honest about being a web demonstration.
Thursday’s plan is simple: make the writing surface feel quiet and immediate.
● Keep Markdown as the source of truth
○ Check emoji offsets in TextKit
○ Try a long note on iPhone
Try changing “quiet and immediate,” checking a task, or editing a table cell. Your draft stays here when you switch examples. Cindermark supplies the structure; the browser draws an interpretation of Ember’s native editor. Open “Under the hood” to inspect the source and changed blocks.
Cindermark supplies the structure. Ember adds TextKit layout, native selection, attachments, and the rest of the app experience.
Open the full playground →Built around the edit.
UTF-16 ranges
Swift-facing blocks and inline spans use the coordinate system expected by NSRange, NSTextStorage, and TextKit.
Focused re-parsing
Ordinary edits return the affected block range. Structural changes can deliberately fall back to a full parse when correctness requires it.
One document model
Blocks, inline spans, statistics, headings, tasks, and wiki links come from the parser instead of a second editor-only scanner.
Swift over Rust
Use a tagged Swift Package with its prebuilt XCFramework, or depend on the lean Rust crate without the binding toolchain.
Know what the parser sees.
The live note shows the useful surface. This complete profile makes the boundary explicit: parsing is Cindermark’s job; visual rendering remains yours.
Blocks
Headings, paragraphs, block quotes, nested lists, tasks, fenced code, tables, horizontal rules, footnotes, callouts, math, raw HTML, and typed Mermaid blocks.
Inline
Emphasis, strong emphasis, links, autolinks, inline code, strikethrough, underline, highlights, color literals, wiki links, footnote references, and inline math.
Editor data
UTF-16 ranges, incremental dirty blocks, checkbox toggling, document statistics, heading extraction, and wiki-link extraction.
Host-rendered
Math, diagrams, raw HTML, attachments, fonts, colors, selection, and layout remain deliberate host-app decisions.
Drop it into an iOS or macOS app.
The published Swift package contains a prebuilt XCFramework, so a consuming app does not need a Rust toolchain. Rust remains one tab away.
.package(url: "https://github.com/renedeanda/cindermark", from: "0.3.0")import Cindermark
let parser = CindermarkParser()
let result = parser.parseEditable(text: "# Hello, Ember")
for block in result.blocks {
let range = NSRange(
location: Int(block.utf16Start),
length: Int(block.utf16End - block.utf16Start)
)
// Apply TextKit attributes inside this range.
}Measure the edit path.
These are native release-build measurements from the published 0.3.0 tag. They describe parser work on this machine, not TextKit layout or browser rendering.
Measured September 24, 2026 on an Apple M4 MacBook Air running macOS 27.0, from the published v0.3.0 tag. Values are rounded Criterion medians from 100 samples.
Criterion release build with fat LTO and one codegen unit. Synthetic notes mix headings, paragraphs, lists, checkboxes, and code blocks.
Methodology and reproducible suite ↗More syntax. The same source contract.
- Math, raw HTML, and Mermaid source recognition.
- Source queries for headings and wiki links.
- Swift-facing editable parsing with UTF-16 ranges.
Questions worth answering.
Short answers to the decisions that matter when a parser enters a real editor.
Can I use Cindermark in an iOS or macOS app?
Yes. Swift Package Manager installs the tagged package and prebuilt XCFramework. Apps using the published binary do not need a Rust toolchain.
How is it different from a normal Markdown parser?
Cindermark is designed around edits. It keeps parser state, reports changed blocks after an edit, and exposes source ranges an editor can map back to its text system.
Does it work directly from Rust?
Yes. The default crate uses the Rust parser without Swift or UniFFI tooling. The ffi feature is opt-in.
Which Markdown syntax does it support?
It is CommonMark-oriented with editor-focused extensions including tasks, tables, callouts, wiki links, highlights, underline, footnotes, math source, and Mermaid blocks. It does not claim complete CommonMark or GFM conformance.
Does it render LaTeX or execute HTML?
No. The parser identifies math and raw HTML as source. The playground escapes HTML and adds a separate on-demand KaTeX and Mermaid presentation layer.
Which release should I install?
Use the published 0.3.0 tag shown in the quickstart. Release notes and migration guidance are linked from the documentation page.
What do the performance numbers mean?
They measure parser work in a native release build. A real editor also pays for text layout, attributed-string updates, attachments, rendering, and input handling.
Where can I ask for help or contribute?
Open a focused GitHub issue with a small Markdown sample and the behavior you expected. Pull requests are welcome after running the parser test suite and reading the contribution guide.
See it in its natural habitat.
Cindermark powers the live Markdown editor in Ember Notes for iPhone, iPad, and Mac. It began with the constraints of a real native editor and remains useful outside that app.
See Ember Notes ↗Open source, with real work to do.
Install Cindermark in an editor, bring a small failing document when you find an edge, or contribute a focused fix. Issues and pull requests are welcome.