Open source · MIT · Swift + Rust

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.

Current release0.3.0

iOS 16+ · macOS 13+
Prebuilt XCFramework
Pure Rust crate

Rust coreSwift Package ManagerUTF-16 rangesWebAssembly playgroundMIT license
Real parser · Local to this tab

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.

Editor release · Markdown noteLive, local, editable
Editor release

Thursday’s plan is simple: make the writing surface feel quiet and immediate.

Before beta

● Keep Markdown as the source of truth
○ Check emoji offsets in TextKit
○ Try a long note on iPhone

SurfaceDecisionMacKeep the caret steadyiPhoneMake every control thumb-sized

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.

Warming up the parser…Updating parser…

Cindermark supplies the structure. Ember adds TextKit layout, native selection, attachments, and the rest of the app experience.

Open the full playground →
Editor primitives / 01—04

Built around the edit.

01 / Position

UTF-16 ranges

Swift-facing blocks and inline spans use the coordinate system expected by NSRange, NSTextStorage, and TextKit.

02 / Change

Focused re-parsing

Ordinary edits return the affected block range. Structural changes can deliberately fall back to a full parse when correctness requires it.

03 / Structure

One document model

Blocks, inline spans, statistics, headings, tasks, and wiki links come from the parser instead of a second editor-only scanner.

04 / Platform

Swift over Rust

Use a tagged Swift Package with its prebuilt XCFramework, or depend on the lean Rust crate without the binding toolchain.

Syntax and editor data

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.

Start in 60 seconds

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.

Swift Package Manager
.package(url: "https://github.com/renedeanda/cindermark", from: "0.3.0")
Swift / TextKit
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.
}
Performance, with context

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.

108 µsIncremental edit · 500 lines
520 µsIncremental edit · 2,500 lines
2.10 msIncremental edit · 10,000 lines
3.45 msFull parse · 2,500 lines

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 ↗
Current release · 0.3.0

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.
Before you adopt it

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.

Production provenance

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 ↗
Use it. Then help shape it.

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.